Design System

Updated:

The Tecton Design System provides web components for building consistent user-experiences that work across various frameworks and platforms and remain in sync with branding and theming. Components are organized by purpose, such as:

  • Forms: q2-input, q2-select, q2-checkbox, q2-btn, q2-form
  • Display: q2-card, q2-list, q2-item, q2-detail, q2-section
  • Feedback: q2-message, q2-loading, q2-tooltip
  • Data Visualization: q2-chart-bar, q2-chart-donut, q2-meter

For complete component reference, see the individual component documentation.

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. If you are using our provided framework wrappers, please see the documentation for working with events in React Wrappers and Vue Wrappers.

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.

Common Patterns

Here are some frequently used component patterns to help you get started quickly.

Form with Validation

<q2-form>
  <q2-input label="Email" id="email" type="email"></q2-input>
  <q2-input label="Password" id="password" type="password"></q2-input>
  <q2-btn intent="workflow-primary" type="submit">Sign In</q2-btn>
</q2-form>

<script>
  document.querySelector("q2-form").addEventListener("submit", (e) => {
    const emailInput = document.getElementById("email");
    const passwordInput = document.getElementById("password");

    if (!emailInput.value) {
      emailInput.errors = ["Email is required"];
      e.preventDefault();
    }
    if (!passwordInput.value) {
      passwordInput.errors = ["Password is required"];
      e.preventDefault();
    }
  });
</script>

Button Pairing

<q2-action-group>
  <q2-btn intent="workflow-secondary">Cancel</q2-btn>
  <q2-btn intent="workflow-primary">Submit</q2-btn>
</q2-action-group>

Collapsible Section

<q2-section label="Account Details" collapsible expanded>
  <q2-detail label="Account Number" value="****1234"></q2-detail>
  <q2-detail label="Account Type" value="Checking"></q2-detail>
</q2-section>

Icon Button

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

Testing

Tecton components are extensively tested with End-to-End (E2E), Unit, and Accessibility tests. This means you don't need to verify core component functionality—we handle that. Your tests should focus on your application logic and how components integrate with your features.

Key test types to consider for your features:

  • E2E Testing - Test complete user flows from the user's perspective
  • Integration Testing - Verify your components work together correctly
  • Accessibility Testing - Ensure your feature meets accessibility criteria (tools like aXe DevTools help here)

Use Test Methods to interact with components in tests without reaching into ShadowDOM.