Proposing changes
Octopus product designers are encouraged to propose changes to our design system accordingly to our contribution model. Depending on the contribution size, create a branch in Figma (Fix and Light contributions) or use the Component Proposal file to introduce your changes (Medium and Large contributions).
Branching
- Create a branch in the Figma Component Library file. Name it @username/changes-you-made, for example, @karolinaszczur/callout-upsell-variant.
- When you’re done making your changes, request review from a Frontend Foundations designer through the Figma interface, providing the details of your proposed change.
- Once your changes are approved, Frontend Foundations designer will merge them into the library. This ensures visibility across modifications introduced to the design system.
Using Component Proposal template
The Component Proposal file is there to guide you through contributing significant changes to an existing component or creating a new one from scratch. Use the How to use this template and the Definition of Ready checklist to ensure following our standards.
Once the contribution is accepted:
- Move the Variants frame to a relevant Page within the Component Library.
- Move the Usage examples to a relevant a dedicated artboard for the component in the Supernova Assets file so you can embed them on the Usage page when documenting the component.
- Ensure the component is published.
Authoring components
Naming
Name of the component should be identical in design and code. Component names use PascalCase and should follow our naming conventions.
Documentation
We primarily document components in our design system documentation. In Figma, each component (or variant) should have a short description of its usage and link to the relevant documentation page.
Layer organization
All layers within a component should be named to inform the intended code implementation. When grouping layers, use an explicit name that describes what’s contained in the group. General principles for component naming will help you create meaningful names for layers, too.
When using text layers, name them to represent the type of information the text contains. E.g. placeholder, title, message.
Properties
All properties and values are written in camelCase.
|
Property type |
Description |
Use cases |
|---|---|---|
|
Variant |
Defines core attributes of a component designers can switch between. |
Defining structural attributes. For example: distinct states or types of elements. |
|
Text |
Exposes editable text within the component. |
For example: providing custom form element label text, customizing error messages. |
|
Boolean |
Toggles visibility of elements within a component. Accepted values are true and false. |
Showing and hiding elements. For example: showing arrow up icon when an Accordion is open, and down icon when it’s closed. |
|
Instance Swap |
Allows inserting and swapping nested components, with optionally predefined components. |
Constructing more complex components without the need to recreate basic components. For example: placing a Button within a Callout. |
Properties: Variants
Use variants to define attributes of a component. They’re composed of variant property and its value, both of which are customizable. Variants often convey most prominent visual differences.
|
Property name |
Example values |
Usage |
|---|---|---|
|
type |
primary, secondary, tertiary |
Defines a hierarchy of component variant usage. Useful in common scenarios such as Button component. |
|
state |
rest (default), focus, active, hover, selected |
Defines interactive behaviors mapping to CSS pseudo-classes. Some of the states might have to be implemented as Boolean property equivalents (e.g.: disabled or readOnly). |
|
isDisabled |
true, false |
Defines if an element is disabled in terms of turning off interactivity or functionality. |
|
isReadOnly |
true, false |
Defines if the element is read only. |
|
isMuted |
true, false |
Defines if an element has a visually less prominent appearance that might hint it’s disabled, but no functionality or interactivity is turned off. |
|
size |
xSmall, small, medium, large, xLarge, xxLarge |
Defines standardized sizes for components. Use t-shirt sizing with a value in parenthesis as the same names might mean different widths for different components (e.g.: xs (14px)). |
|
width |
xSmall, small, medium, large, xLarge, xxLarge, fullWidth |
Defines standardized width for components. Use t-shirt sizing with a value in parenthesis as the same names might mean different widths for different components (e.g.: xs (14px)). |
|
grid |
single, 2-column, 3-column |
Defines the space that content can fill (e.g.: cards inside a Dialog). |
|
validation |
neutral, error, success |
Defines the validation state of the provided data. |
|
shape |
square, circle |
Defines the shape of the component. |
|
{item}Position |
top, bottom, left, right |
Defines the position of an element. E.g. an arrow in a Tooltip component. |
|
{item}Count |
1, 2, 3, 4, 5, 6, 7 |
Defines the number of nested component instances. E.g. a number of Radio options in a Radio Group. |
Note that the table above doesn’t cover all possible cases of variants that you might need to create. When in doubt, ask yourself:
- Can the name and the options be easily understood without additional context and documentation?
- Does it accurately represent what the variant does?
The clearer and more succinct the naming, the better.
Naming properties
Do not use special characters in property names, as they are not supported in the code implementation.
|
✅ DO |
❌ DON’T |
|---|---|
|
isSysOrAdminUser |
isSys/AdminUser |
|
hasEdit |
edit? |
Using variants for Boolean properties
In some cases, Figma variants don’t map neatly to code implementation. For example, a Button can simultaneously be disabled and in focus. To avoid chaining states (e.g. active focus) for maintenance and clarity reasons (see Sorry State of States by Nathan Curtis), we recommend separating isDisabled and isReadOnly states and using true and false as the property values.
Properties: Text
Use the text property to indicate that text is editable within a component. Be aware that the text property currently isn’t available to use with rich text.
We preface all text property names with the :pencil: emoji (✏️ ) to signify that it’s editable. Because Figma doesn’t allow property nesting, if a text element is only displayed when an additional, boolean property is toggled, we preface the property name with downwards arrow with tip rightwards ( ↳). For example:
- Text property: ✏️ optionValue
- Nested text property: ↳ ✏️ fieldValue
Properties: Boolean
Use the boolean property to set true or false values that control layer visibility. You can attach the same boolean property to multiple layers to show and hide them together. When naming a boolean property, consider the following naming conventions:
|
Boolean property name |
Example values |
Usage |
|---|---|---|
|
is-{verb} |
isDisabled, isReadonly, isRequired, isLoading |
Useful when portraying that a parent component is in a certain state that cannot be expressed using property variants, especially when controlling visibility of multiple items. |
|
has-{item} |
hasIcon |
Useful when portraying that a parent component has a specific, singular item. |
|
showHide-{item} |
showHideExpandCollapseIcon |
Useful when specificity in the element we’re controlling is necessary for clarity. |
Properties: Instance swap
Use the instance swap property to indicate that an instance nested in the component can be changed. Always set preferred instances designers can choose from. The benefit of using instance swap is the ability to easily change a nested component without the need to create more unique variants. This is especially useful when nesting icons, but can be used for other components as well.
It’s possible to override the settings (color, visibility, etc.) of the nested component using instance overrides. Applied overrides will only be available for the nested component instance—they won’t affect the original component.
Generally, we steer away from using overrides as they lessen the consistency of the design system elements, but we’re open to consider them where absolutely warranted. Creating overrides also means additional engineering work will be required, often going against existing component best practice constraints, so use it sparingly.
Nested Instances and Sub components
Use exposing nested instances to show their component properties alongside the properties of the top-level component. Exposing nested instances makes it easy to edit nested properties without the need of going through multiple layers to find them. Only expose the nested instances that should be edited.
Currently, it’s impossible to only expose specific properties in Figma. By default, all properties will be exposed.
When creating sub components, which shouldn’t be used on their own, but as building blocks for more complex components, use the following naming pattern:
- start with prefixing the component name with underscore (_)
- if the sub component is only relevant to a group of components, start with adding the group name (e.g.: _formElements)
- finish with name of the component, which could consist of several words (e.g. formElements.input or formElements.radioGroup.items)
Multiple components vs multiple variants
In some cases, it’s not evident if similar components should be handled as separate or variants of the same component because of similarities. When deciding between these two approaches, consider:
- Does the change strictly visual or significantly alter the functionality of the component? When new functionality is added, it can warrant creating a separate component (that might or might not inherit from another component through nested instances).
- Example: Avatar vs AvatarStack. The latter uses Avatar with added functionality that is irrelevant to all use cases.
- Does the chosen approach negatively influence maintenance? If the components are separated but very similar in terms of appearance and function, it increases the maintenance cost on the design and code sides.
- Example: PopoverComplex and PopoverHelp. Both are similar enough to be variants of the same component, reducing the maintenance overhead.