Design System

Updated:

The Tecton Suite includes a set of Tecton components that enable us to drive UI consistency across all products.

These are included whether you're using the design system, building on top of a platform, or constructing a module that will be displayed on a platform.

About Web Components

Today, if you're doing web development, there are countless options you may be utilizing to present content to your users. Some of these options include server-side rendering using languages like Ruby, Python, or Javascript. Other options include client-side rendering with frameworks like React, Vue, Ember, or Angular.

Because of this, we chose to build out our design system with web components. Using a symphony of browser features, we can create custom HTML elements complete with their own attributes, styling, and features.

Each of the components that Tecton publishes goes through an extensive design review, is well-tested, and is built with accessibility in mind. Additionally, when bugs or necessary improvements are identified, we address them in our codebase, and then all the teams using the design system only need to take an update to utilize them.

Using Web Components

Because web components get registered with the browser as HTML elements, using them is pretty straightforward. For example, if you want to display a q2-btn element with a q2-icon on the left side, it's as simple as this:

<q2-btn intent="workflow-primary">
  <q2-icon type="edit"></q2-icon>
  <span>Edit</span>
</q2-btn>

Below, you will find descriptions of the various ways you can use each of these features within web components. Every element's documentation page documents what is available.

Properties

Each component in the design system allows you to customize its use in various ways by exposing attributes and properties that modify how it looks or behaves. While attributes and properties are two ways of achieving the same result, their distinction is worth documenting here.

Attributes are how you set the state of an element via HTML. On the other hand, you use properties to set the state of an element via JavaScript. The difference can be easily seen here:

<!-- Setting with an attribute -->
<q2-btn intent="workflow-primary"></q2-btn>

<!-- Setting with a property -->
<script>
  const button = document.querySelector("q2-btn");
  button.intent = "workflow-primary";
</script>

Some properties are defined as boolean, meaning they can only have a value of true or false. These can be utilized in the following ways:

<!-- ATTRIBUTE -->
<q2-btn hide-label></q2-btn>
<!-- OR -->
<q2-btn hide-label="true"></q2-btn>

<!-- PROPERTY -->
<script>
  const button = document.querySelector("q2-btn");
  button.hideLabel = true;
</script>

In rare cases, properties can be objects or arrays. An example is when data is passed to a chart or table. While these cannot be set via attributes, they can easily be set using JavaScript.

const chart = document.querySelector("q2-chart-bar");
chart.data = [
    {
        value: 1048,
        name: 'March',
        id: 'march',
    },
    {
        value: 580,
        name: 'April',
        id: 'april',
    },
    {
        value: 735,
        name: 'May',
        id: 'may',
    },
    {
        value: 465,
        name: 'June',
        id: 'june',
    },
    {
        value: 927,
        name: 'July',
        id: 'july',
    },
]

Please visit each component's documentation page for a full list of exposed properties.

Events

Within the Tecton components, you can use events to listen for when the user performs an action, such as typing a value into an input field or clicking a button. Like attributes and properties, events can be used in several different ways.

<!-- In HTML with an attribute -->
<q2-input label="Name" oninput="myHandler"></q2-input>

<script>
  const myHandler = (event) => {
    console.log("VALUE", event.detail.value);
  }
</script>
<!-- In JavaScript with a property -->
<q2-input label="Name"></q2-input>

<script>
  const input = document.querySelector("input");
  input.oninput = (event) => {
    console.log("VALUE", event.detail.value);
  }
</script>
<!-- In JavaScript with addEventListener -->
<q2-input label="Name"></q2-input>

<script>
  const input = document.querySelector("input");
  input.addEventListener("input", (event) => {
    console.log("VALUE", event.detail.value);
  })
</script>

Within Tecton, some events have the same name as native event names like change, input, and so on. Please see the documentation on each component to learn what events are available and what data they provide.

Methods

Many components have methods that you can call to perform various actions that may not make sense to do by updating an attribute or property. They can be invoked the same way you might call other methods on an element like element.click() or element.focus(). For example:

const chart = document.querySelector("q2-chart-donut");
chart.clearSelection();

All methods defined by Tecton are asynchronous by default, so you may need to take that into consideration when using them. Please see the documentation on each component to learn what methods are available and the arguments you may pass to them.

Writing Tests

When building new features, a substantial effort typically goes into testing components like form fields, buttons, charts, and dropdowns to ensure they behave as expected across various scenarios, browsers, and devices. If you're using the Tecton Design System, you may wonder, "What tests should I be focusing on then?"

Within Tecton, we cover a broad range of End-to-End (E2E), Unit, and Accessibility tests for our components and continuously add more. This means you don't need to check core functionality within these tools. However, if you're unsure whether something specific is covered, please ask! If it's not, we'll ensure it gets added.

Tests remain crucial to maintaining robust features, though now you just don't have to write as many of them. With Tecton's Test Methods, interacting with components is even simpler since it is unnecessary to reach into the ShadowDOM to interact with them. However, there are still some key test types to consider for your features:

  • End-to-end (E2E) Testing - Simulates real-world use cases by testing the complete application flow from a user's perspective.
  • Regression Testing - Ensures new changes don't impact existing functionality in the app.
  • Unit Testing - Validates individual functions or components you write in isolation to ensure they behave as expected.
  • Integration Testing - Confirms that different parts of the system interact and function correctly together.
  • Accessibility Testing - Helps ensure that your entire feature meets a number of accessibility criteria. We recommend using tools like aXe DevTools for this.
  • Security Testing - Identifies vulnerabilities to protect user data and maintain trust.
  • Usability Testing - Gathers user feedback on the feature's ease of use and intuitiveness.
  • Performance Testing - Assesses the app's speed, responsiveness, and stability under various conditions.
  • Contract Testing - Verifies that interconnected parts of the system, like the front end and back end, communicate effectively by following agreed-upon data formats.
  • Visual-Diff Testing - Checks for consistency in appearance and layout across devices and releases.

While your use cases may vary, we believe thoroughly testing your features helps you ensure you maintain high standards of quality and reliability, especially when leveraging Tecton's foundational components and tooling.