loading

v32.1.1

select option

Samples' Guidelines

Guidelines on how to build samples for ink's multiple environments

LAST UPDATED: Nov 2021

Overview

The ink ecosystem contains five different environments which utilize component samples. All of these environments adhere to ink's best practices, so they share some general guidelines. However, each one of them also serves a unique purpose in the ink product, therefore, they also have some environment-specific guidelines.

General Guidelines

Before starting to re-write samples it's very important to make yourself acquainted with the UX Writing guidelines. Make sure that you’re not duplicating existing content. If you're adding samples to an existing file that was not refactored yet, follow the Guidelines and not the convention in the samples. Let's make each new sample one less sample we need to refactor in the future.

The order of samples in all environments (therefore in samples.js) should go from the simplest base case (Default sample) first to more complex cases last.

  • The first (default) sample should include the minimum amount of props and other components needed for the component to visually work. It should ideally never contain parent or sibling elements but could contain child elements. Be mindful of not causing ambiguity about what component the sample is supposed to illustrate.
  • All other samples should be visual variations of this default case and gradually increase in complexity (adding/changing props). This helps beginners to better understand the different parts of components.
  • When making samples specific for a single environment, they should go after the shared samples in this specific order: docs first, then exposé and lastly playroom.
  • Deprecated and exposé-only samples should go last no matter their complexity.

All the sample names, when applicable, should be written in human terms and contain the name of the component; prefer describing what the sample achieves or looks like instead of the props being used for example: "Field with helpers and input".

  • Each sample name should be unique per component
  • Refrain from using backticks in the name because it can potentially break backstop

Samples should be realistic in their usage. Common cases and patterns are highly encouraged.

  • Internal props and components should not be made available to the public. Samples for these cases should exist for testing purposes in the expose environment, but should not be available to users through the docs or playroom.
  • Samples should take into account the component's usage. If a specific prop or way of building a component is widely used/needed, samples should exist for that case.
  • Samples should be kept up to date with the latest components and best practices. They should be the role model for the use of ink and design in Carta. Since samples are commonly used as an initial reference implementation, keeping them updated ensures that more modern patterns are disseminated.

The environments available are: docs, expose and playroom.

  • Each sample should work for as many environments as possible, but be mindful of each environment's purpose in relation to the sample.
  • Explorer samples are set in the PropData.js file in each component's folder.
  • BackstopJS will screenshot all expose samples in its initial load state. Additional screenshot tests can be added to a corresponding .backstop.json file in exposé folder. Initial sample screenshots can be skipped by adding skipInitialBackstop: true to the sample snippet.

Environment Specific Guidelines

Docs - ink.carta.com

The documentation is the main source of knowledge about ink. Therefore, documentation samples should encompass all visual and some contextual examples of ink components, and showcase their intended usage.

  • On more complex components, visual props could be explained on the sample itself if possible. Props can be explained using its own content (see Field for examples) or through the sample description.
  • Use real language instead of "Lorem ipsum" in more complex/contextual samples. Showing how real content is displayed in a specific component encourages more correct usage of the component.
  • Each component should have at least as many visual variations' samples as they have visual props. The alternative to this is the user adding prop by prop to see how the component reacts which is a bad user experience. This also helps new users that may not know the props yet to rapidly and easily understand what a specific prop is doing in the component.
  • Props and visual variations that are unused or have little usage (or that we don't want to encourage the use of) should be left off of the docs. These samples should be researched and if possible, tasks to remove them from the component should be created.
  • Each component should have at least one component integration sample, showing it in its usual surrounding context. Showing a real-world example helps the user contextualize what each component is supposed to be used for.
  • The contextual samples should be as interactive as possible without cluttering the sample code.
  • A description can be provided to the sample to explain context, link to another section of the documentation or explain functionalities. The description is given as another key/value pair in the sample object and it only shows in the docs, not in the Exposé nor in Playroom.
  • Contextual samples will usually need "solidBackground: true" to accurately reflect the look and feel of our production environment. This sample object key pair can also be used on specific samples, if the checkerboard background gets in the way.

Expose

The purpose of the Exposé is automated visual regression testing (aka BackstopJS) and integration testing (aka Cypress). Because it is used for testing, it is an internal tool for the Ink team.

  • It's ok to use "Lorem ipsum" and placeholders in these samples. Since these are just for testing purposes there's no problem in using placeholders for text and content in these.
  • Exposé only samples should be close to their visual counterparts on the samples.js file when they exist, otherwise they should be at the end of the file. Be mindful of the order of samples as they'll be in the Exposé and how easy it would be for the next developer to understand your samples' complexity progression.
  • We should have common and more edge integration cases. These cases are important to test the component's breadth so, for example, we should have extremely long texts, or multiple clicking interactions. These should go in a single sample called: "Edge Cases" and can have internal sections.

BackstopJS

We use BackstopJS to test as many visual variants of each component as needed. Make each visual sample as atomic as possible, so the diffs don't get polluted as a ripple effect and are specific to the visual changes that were made. If possible, stay away from stateful samples for visual testing, unless they are simple binary interactions. Checkbox clicks, dropdown opening and closing, twiddle tables, are some examples of binary states we can test with Backstop.

All Exposé samples are automatically included as individual snapshots. This only tests the initial state on load. Additional screenshot tests can be added to a corresponding .backstop.json file in exposé folder. Initial sample screenshots can be skipped by adding skipInitialBackstop: true to the sample snippet.

Cypress

Used to test behavior, not implementation. Cypress is for testing interactive behavior: what the final user would do when using that component. Use stateful samples for the integration test.

  • Don't test if a component renders, that is React's job
  • Don't test if the component color is "X", that is BackstopJS's job.

Playroom

Playroom is our design and ink experimentation tool. Its purpose is to allow designers and engineers to make and share design mockups and code in an easy, fast way. It's not a code beginner friendly tool. If you want to learn more about it, take a look at Playroom 101.

  • Playroom samples should not be too big or complex because it causes the editor to freeze. Big samples also take more time to show when hovering, which can unnecessarily delay development.
  • Not all samples need to be in Playroom, add only those that truly represent the most common use cases of the component. Remember these samples are to be used by designers and engineers who will be trying to build something fast. Having to search through multiple almost identical samples makes the job harder.
  • The contextual samples from the docs should never be in Playroom. They are too broad and don't actually make sense in Playroom.
  • Playroom should be fast and easy to use so its samples should be usable out of the box with little to no modification. No huge implementations that the user needs to delete a lot of code from in order to use.
  • Components that have children should have a base playroom sample with only a placeholder instead of actual children components. This allows for more flexibility when nesting components. Erasing a placeholder is way easier than erasing several nested children.

Explorer

It's still in early access but allows our non-technical users to interact and experiment with props in real time providing immediate visual feedback.

*At the moment it's mostly a visual experimentation tool because stateful components are not working on it, so samples should also allow for as much visual cue on how to use the props as possible.

  • Should have as many pre-defined props as possible without introducing bad cases/patterns. This is a way to show the components' breadth, so the more props we can show the user how to use, the better.
  • If needed, the samples should have children to show how the component works. For example all spacing components should have children (Box, VStack, Column, etc). Also root components would have them as well (NewTable, Block, etc)
  • If your component needs a state or a parent to work it might not work on the explorer. If that's the case, add @skipexplorer true to the jsdoc strings on the component's main .tsx file. Like this on line 125:

Typeahead skipexplorer example

Is this page helpful?