Skip to content

Design Library

The design core library creates reusable components used throughout our products (e.g., airs, integrates, Jira).

Introduction

The fluid attacks design components library is an open-source npm package written in TypeScript and built with React.

Public Oath

Contributing

Please read the contributing page first.

Design standards

As our products rapidly evolve, the user interface is constantly modified. Since the platform and website redesign in 2024, we encountered the need to create a robust and maintainable design library to hold all the basic elements used to construct digital interfaces.

For this purpose, we applied different known software standard principles:

  1. Atomic Design: a methodology for designing and building user interfaces by breaking them down into progressively complex components, similar to how atoms combine to form molecules in chemistry, allowing for reusable and consistent components across an application, with the core idea being to create a hierarchical structure of UI elements, starting from basic “atoms” and building up to more complex “molecules”, “organisms”, “templates”, and finally “pages”.
  2. KISS, “Keep It Simple, Stupid”: a software development guideline that encourages developers to keep their code and systems as simple as possible. The principle is based on the idea that the simplest solution is often the best, and unnecessary complexity should be avoided.
  3. DRY, “Don’t Repeat Yourself”: a software development principle that aims to reduce the amount of repetitive code and logic in a system. This can help improve code maintainability, reduce the potential for errors, and streamline the development process.
  4. YAGNI, “You Aren’t Gonna Need It”: a software development principle that encourages developers to only add features when they are required, rather than trying to predict future needs.
  5. Single Responsibility (SRP): a component should have only one specific, well-defined purpose or functionality, and should not be responsible for multiple unrelated tasks; essentially, a component should only have one reason to change, making it more modular, easier to understand, maintain, and test independently.

Getting Started

The components are stored in the common/design/src/components directory, each one must contain an index.(ts|tsx) file with the React reusable component and optional files such as:

  • types.ts: To specify the modifiable attributes of the component using types or interface.
  • styles.ts: To create the custom-styled components and different CSS styling props.
  • utils.ts: To add util functions, (e.g., filters, calculations, transformations).
  • index.stories.tsx: To add the storybook file to visualize and test the component.

Styling and Theming

The styling of components is done using both Styled Components and Tailwind.

The storybook is a workshop page to showcase the UI components. It is a public domain and is the true source for keeping all digital products in sync with the design team of Fluid Attacks.

All components can be test locally using Storybook, Eslint and Stylelint, running the following jobs:

Terminal window
m . /common/design

The local storybook can run in localhost:6006 or any other specified port available.

Testing

Besides visually testing the components, Storybook also provides the packages @storybook/test and @storybook/addon-interactions that integrates the component stories with a testing environment powered using Jest. With this feature, we use the same story as a mock and can validate the components’ render and user interactions.

To create a test, inside the index.stories.tsx file create a play function, adding the expect and user events inside it.

import { expect, within } from "@storybook/test";
...
Default.play = async ({ canvasElement, step }): Promise<void> => {
const canvas = within(canvasElement);
await step("should render a Button component", async (): Promise<void> => {
await expect(
canvas.getByRole("button", { name: "Button text" }),
).toBeInTheDocument();
await expect(canvas.getByTestId("arrow-right-icon")).toBeInTheDocument();
});
};

This tests are run in production and local environment directly in the component story using the interactions addon.

Test-light Test-dark

Helpful resources