
# Naming

> The following set of principles guide our team when naming things in the system. These principles are loosely based on the guidelines from Brad Frost’s CSS Architecture for Design Systems.

### Make it modular

Modularity reduces complexity and improves our system’s reusability. This applies to our naming as well. Different parts of the design system need to be clearly separated.

### Keep it consistent

Consistency enhances clarity and makes our design system more predictable and easy to use. We use the same language and naming wherever possible.

### Prioritize legibility

Developers and designers should be able to understand the system at a glance and understand the structure and purpose of any given part.

### Avoid conflicts

It’s critical to ensure that the design system’s naming doesn’t conflict with other libraries and systems. This is accomplished by the provided namespacing.

### Clarity over succinctness

The system may seem verbose, but it delivers clarity and resilience in exchange. Keeping naming legible and scalable sometimes means sacrificing a shorter syntax.

---

### Semantic colors

Semantic colors carry meaning and imply how and where they should be used. Each semantic color name contains a role, a modifier, and a theme mode. This accommodates needs such as state, interactivity, and emphasis for different Kesko brands. For example, a&nbsp;component may require color variations for `:hover` and `:focus` states.

- **Naming structure:** `k-color-{role}-{modifier}-{theme}`
- **Role:** Each color has a specific role in the Kesko Design System such as `accent`, `border`, `text`, `status`, or `bg`.
- **Modifier:** Modifiers are optional and may include variations such as `weak`, `strong`, `active`, `hover`, or `success`.
- **Theme:** User interface theme modes, such as `light` or `dark`.
- **Usage example:**
  - `k-color-text-accent`
  - `k-color-text-on-accent`
  - `k-color-bg-accent`
  - `k-color-bg-highlight`
  - `k-color-status-error`
  - `k-color-status-info`

### Primitive colors

For the Kesko primitive palette, we use numeric scales (`100`, `200`, `300`, ..). This provides clear ordering and makes it easy to add values between the existing tokens when necessary.

- **Naming structure:**
  - `k-color-{name}-{variant}`
- **Valid characters:** Allowed characters include lowercase ASCII letters (`a-z`) and hyphens (`-`). Do not use uppercase characters, symbols, underscores (`_`), dots (`.`), or digits (`0-9`).
- **Usage example:**
  - `k-color-orange-100`
  - `k-color-orange-200`
  - `k-color-red-100`
  - `k-color-red-200`
  - `k-color-blue-100`
  - `k-color-blue-200`
- **Categories:**
  - Orange
  - Beige
  - Blue
  - Green
  - Purple
  - Red
  - Teal
  - Yellow
  - Neutral
- **Tints and shades:**
  - `100`
  - `200`
  - `300`
  - `400`
  - `500`
  - `600`
  - `700`
  - `800`
  - `900`
  - `1000`
  - `1100`
  - `1200`

---

## Components

Kesko’s component library ship as React components in addition to matching Custom Elements and CSS classes so that consumers without React can reach the same visual styling through `@kesko/css`.

### React components

- **Format:** `PascalCase`, for example `Button`, `Spinner`, `Stack`, `VisuallyHidden`.
- **Noun rather than verb:** Components are not actions, they are conceptually “things.” Prefer `Animation` over `Animating`.
- **Meaningful:** Not over specific, not overly abstract.
- **Short:** Maximum of 2 words. Prefer 1 word when possible.
- **Pronounceable:** We want to be able to talk about them.
- **Usage examples:**
  - `<Button />`
  - `<Input />`
  - `<Spinner />`
  - `<Stack />`
  - `<VisuallyHidden />`

### Custom elements

- **Naming structure:** `{prefix}-{name}`.
- **Prefix:** Component names always start with a prefix and a hyphen. For example `k-stack` or `k-spinner`. “K” stands for “Kesko”. Prefixing is critical to ensure that our naming doesn’t conflict with other systems.
- **Noun rather than verb:** Components are not actions, they are conceptually “things.” It is better to use nouns instead of verbs, such as `<k-animation>` instead of `<k-animating>`.
- **Must contain a hyphen:** Must have at least one hyphen (`-`), such as `k-element`.
- **Valid characters:** Allowed characters include lowercase ASCII letters (`a-z`) and hyphens (`-`). Do not use uppercase characters, symbols, underscores (`_`), dots (`.`), or digits (`0-9`).
  **Meaningful:** Not over specific, not overly abstract.
- **Short:** Maximum of 2 words after `k-` prefix.
- **Pronounceable:** We want to be able talk about them.
- **Custom element spec compliant:** Don’t use the following reserved names:
  - `annotation-xml`
  - `color-profile`
  - `font-face`
  - `font-face-src`
  - `font-face-uri`
  - `font-face-format`
  - `font-face-name`
  - `missing-glyph`
- **Usage examples:**
  - `<k-alert>`
  - `<k-badge>`
  - `<k-stack>`
  - `<k-icon>`
  - `<k-divider>`
  - `<k-visually-hidden>`

---

## CSS Properties

- **Naming structure:** `var(--k-{component}-{property})` for public properties.
- **Private properties:** `var(--_k-{component}-{property})` for private properties.
- **Prefix:** `--k-` prefixes a public custom property, meaning developers can use it to fine tune components. `--_k-` prefixes a private custom property, which is reserved for internal design system use.
- **Usage examples:**
  - `var(--k-button-border-radius)`
  - `var(--k-button-font-size)`
  - `var(--k-button-background)`
  - `var(--k-button-border-radius)`

---

## Design Tokens

Designers and developers should be able to understand the purpose of a design token at a glance. To make sure naming stays consistent and legible, we follow these guidelines for design tokens:

- **Naming structure:**
  - `{prefix}-{category}-{name}-{variant}`
  - `{prefix}-{category}-{subcategory}-{name}-{variant}`
- **Prefix:** Design token names always start with a prefix and a hyphen. For example `k-color-accent` or `k-font-size-xl`. “K” stands for “Kesko”. Prefixing is critical to ensure that our naming doesn’t conflict with other systems.
- **Noun rather than verb:** Design Tokens are not actions, they are conceptually “things.” It is better to use nouns instead of verbs, such as `k-color-success` instead of `k-color-succeed`.
- **Valid characters:** Allowed characters include lowercase ASCII letters (`a-z`) and hyphens (`-`). Do not use uppercase characters, symbols, underscores (`_`), dots (`.`), or digits (`0-9`).
- **Default value:** When naming sizes, `{prefix}-{category}-{name}-md` is always the default value.
- **Categorization:** Design token names always include at least one category, like `color`,`font`, or similar. If it makes sense, you can also include a subcategory, for example `k-font-size-xl` or `k-color-status-error`.
- **Usage examples:**
  - `k-color-accent`
  - `k-color-text`
  - `k-color-text-link`
  - `k-color-text-on-accent`
  - `k-color-bg`
  - `k-color-bg-surface`
  - `k-color-status-error`
  - `k-color-status-success`
  - `k-font-size-xl`
  - `k-font-weight-bold`
  - `k-font-family-sans`
  - `k-font-leading-md`
- **Font weights:**
  - `black`
  - `bold`
  - `medium`
  - `regular`
- **Categories and subcategories:**
  - Color
    - Accent
    - Bg
    - Border
    - Fill
    - Overlay
    - Status
    - Text
    - Orange
    - Beige
    - Blue
    - Green
    - Purple
    - Red
    - Teal
    - Yellow
    - Neutral
    - Neutral Dark
    - Brand
  - Font
    - Family
    - Leading
    - Size
    - Weight
  - Layer
  - Motion
    - Duration
    - Easing
  - Opacity
  - Radius
  - Shadow
  - Size
    - Border
  - Space

---

## Sizes

Kesko Design System defines semantic sizes using the t-shirt metaphor. This makes it possible for anyone, technical or non-technical person, to understand the differences and how they relate to each other at a glance.

- **Keep it consistent and short:** Always use the short form version (`sm`, `md`, `lg`, `xl`) when naming things. This makes it quicker for developers and designers to reference the sizes.
- **Default size:** `md` is always the default value.
- **Larger than default:** When you want to define a size larger than medium, use `lg`, `xl`, `2xl`, `3xl`.
- **Smaller than default:** When you want to define a size smaller than medium, we use `sm`, `xs`, `2xs`, `3xs`.
- **Usage example:**
  - `k-font-size-2xl`
  - `k-font-size-xl`
  - `k-font-size-lg`
  - `k-font-size-md`
  - `k-font-size-sm`

---

## Styles

Our design system styles follow a simple naming structure based on `.{prefix}-{name}-{modifier}` format.

- **Naming structure:** `.{prefix}-{name}-{modifier}`.
- **Prefix:** Styles always start with a prefix and a hyphen. For example `.k-button` or `.k-input`. “K” stands for “Kesko”. Prefixing is critical to ensure that our naming doesn’t conflict with other systems.
- **Modifiers:** Modifier is a flag on an element. Use them to change appearance or behavior. For example `.k-button-primary` or `.k-button-outline`.
- **Status:** To indicate status, we use a specific class name `.k-is-{status}`. For example: `.k-is-loading`.
- **Usage examples:**
  - `.k-button`
  - `.k-input`
  - `.k-button-outline`
  - `.k-is-loading`

---

## Properties

When naming component properties, it’s important to pay attention to the consistency between the different components so that the API stays as predictable as possible. The same conventions apply to component properties in Figma.

### React props

- **Mirror HTML where possible:** When an equivalent HTML attribute exists, use the same name — e.g. `disabled`, `size`, `type`. This makes the React API read naturally alongside native element properties and is especially important for form components.
- **Format:** `camelCase` for multi-word names (e.g. `onPress`, `expand`), lowercase for single-word names (e.g. `size`, `variant`). Event handlers follow the `on{Event}` pattern (e.g. `onPress`, `onFocus`).
- **Meaningful:** Not over specific, not overly abstract.
- **Short:** Maximum of 2 words. Prefer 1 word when possible.
- **Pronounceable:** We want to be able to talk about them.
- **Sizes:** Use a property called `size` and follow our [sizes guideline](#sizes) for naming.
- **Disabled state:** Use a boolean property named `disabled`.
- **Style variants:** Use a property called `variant` for style variants such as `primary`, `secondary`, or `plain`.
- **Reserved names:** Avoid property names that collide with React’s own reserved names:
  - `children`
  - `className`
  - `style`
  - `ref`
  - `key`
  - `dangerouslySetInnerHTML`

### Custom element attributes

- **Generic rules:** Follow the [HTMLElement API](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement) to make sure the developer- and LLM-facing APIs are as predictable as possible. This is especially important for form components.
- **Valid characters:** Allowed characters include lowercase ASCII letters (a-z) and hyphens (-). Do not use uppercase characters, symbols, underscores (\_), dots (.), or digits (0-9).
- **Meaningful:** Not over specific, not overly abstract.
- **Short:** Maximum of 2 words. Prefer 1 word when possible.
- **Pronounceable:** We want to be able to talk about them.
- **Sizes:** Use a property called `size` and follow our [sizes guideline](#sizes) for naming.
- **Disabled state:** Use a boolean property named`disabled`.
- **Style variants:** Use a property called `variant` for style variants such as `success`, `error` and such.
- **Reserved names:** You should be careful that the property names do not conflict with existing standardized prototype members. Reserved names include:
  - `align`
  - `title`
  - `lang`
  - `translate`
  - `dir`
  - `dataset`
  - `hidden`
  - `tabIndex`
  - `accessKey`
  - `draggable`
  - `spellcheck`
  - `autocapitalize`
  - `contentEditable`
  - `isContentEditable`
  - `inputMode`
  - `offsetParent`
  - `offsetTop`
  - `offsetLeft`
  - `offsetWidth`
  - `offsetHeight`
  - `style`
  - `innerText`
  - `outerText`
  - `oncopy`
  - `oncut`
  - `onpaste`
  - `onabort`
  - `onblur`
  - `oncancel`
  - `oncanplay`
  - `oncanplaythrough`
  - `onchange`
  - `onclick`
  - `onclose`
  - `oncontextmenu`
  - `oncuechange`
  - `ondblclick`
  - `ondrag`
  - `ondragend`
  - `ondragenter`
  - `ondragleave`
  - `ondragover`
  - `ondragstart`
  - `ondrop`
  - `ondurationchange`
  - `onemptied`
  - `onended`
  - `onerror`
  - `onfocus`
  - `onfocusin`
  - `onfocusout`
  - `oninput`
  - `oninvalid`
  - `onkeydown`
  - `onkeypress`
  - `onkeyup`
  - `onload`
  - `onloadeddata`
  - `onloadedmetadata`
  - `onloadstart`
  - `onmousedown`
  - `onmouseenter`
  - `onmouseleave`
  - `onmousemove`
  - `onmouseout`
  - `onmouseover`
  - `onmouseup`
  - `onmousewheel`
  - `onpause`
  - `onplay`
  - `onplaying`
  - `onprogress`
  - `onratechange`
  - `onreset`
  - `onresize`
  - `onscroll`
  - `onseeked`
  - `onseeking`
  - `onselect`
  - `onstalled`
  - `onsubmit`
  - `onsuspend`
  - `ontimeupdate`
  - `ontoggle`
  - `onvolumechange`
  - `onwaiting`
  - `onwheel`
  - `onauxclick`
  - `ongotpointercapture`
  - `onlostpointercapture`
  - `onpointerdown`
  - `onpointermove`
  - `onpointerup`
  - `onpointercancel`
  - `onpointerover`
  - `onpointerout`
  - `onpointerenter`
  - `onpointerleave`
  - `onselectstart`
  - `onselectionchange`
  - `nonce`
  - `click`
  - `focus`
  - `blur`
  - `namespaceURI`
  - `prefix`
  - `localName`
  - `tagName`
  - `id`
  - `className`
  - `classList`
  - `slot`
  - `attributes`
  - `shadowRoot`
  - `assignedSlot`
  - `innerHTML`
  - `outerHTML`
  - `scrollTop`
  - `scrollLeft`
  - `scrollWidth`
  - `scrollHeight`
  - `clientTop`
  - `clientLeft`
  - `clientWidth`
  - `clientHeight`
  - `attributeStyleMap`
  - `onbeforecopy`
  - `onbeforecut`
  - `onbeforepaste`
  - `onsearch`
  - `previousElementSibling`
  - `nextElementSibling`
  - `children`
  - `firstElementChild`
  - `lastElementChild`
  - `childElementCount`
  - `onfullscreenchange`
  - `onfullscreenerror`
  - `onwebkitfullscreenchange`
  - `onwebkitfullscreenerror`
  - `setPointerCapture`
  - `releasePointerCapture`
  - `hasPointerCapture`
  - `hasAttributes`
  - `getAttributeNames`
  - `getAttribute`
  - `getAttributeNS`
  - `setAttribute`
  - `setAttributeNS`
  - `removeAttribute`
  - `removeAttributeNS`
  - `hasAttribute`
  - `hasAttributeNS`
  - `toggleAttribute`
  - `getAttributeNode`
  - `getAttributeNodeNS`
  - `setAttributeNode`
  - `setAttributeNodeNS`
  - `removeAttributeNode`
  - `closest`
  - `matches`
  - `webkitMatchesSelector`
  - `attachShadow`
  - `getElementsByTagName`
  - `getElementsByTagNameNS`
  - `getElementsByClassName`
  - `insertAdjacentElement`
  - `insertAdjacentText`
  - `insertAdjacentHTML`
  - `requestPointerLock`
  - `getClientRects`
  - `getBoundingClientRect`
  - `scrollIntoView`
  - `scroll`
  - `scrollTo`
  - `scrollBy`
  - `scrollIntoViewIfNeeded`
  - `animate`
  - `computedStyleMap`
  - `before`
  - `after`
  - `replaceWith`
  - `remove`
  - `prepend`
  - `append`
  - `querySelector`
  - `querySelectorAll`
  - `requestFullscreen`
  - `webkitRequestFullScreen`
  - `webkitRequestFullscreen`
  - `part`
  - `createShadowRoot`
  - `getDestinationInsertionPoints`
  - `nodeType`
  - `nodeName`
  - `baseURI`
  - `isConnected`
  - `ownerDocument`
  - `parentNode`
  - `parentElement`
  - `childNodes`
  - `firstChild`
  - `lastChild`
  - `previousSibling`
  - `nextSibling`
  - `nodeValue`
  - `textContent`
  - `hasChildNodes`
  - `getRootNode`
  - `normalize`
  - `cloneNode`
  - `isEqualNode`
  - `isSameNode`
  - `compareDocumentPosition`
  - `contains`
  - `lookupPrefix`
  - `lookupNamespaceURI`
  - `isDefaultNamespace`
  - `insertBefore`
  - `appendChild`
  - `replaceChild`
  - `removeChild`
