Code Monkey home page Code Monkey logo

design_system_lints's Introduction

Design System Lints

Build Status codecov License: MIT pub package

A collection of lints and code edits enforcing UI standards throughout a codebase.

An analyzer rule package built using Sidecar

Overview

As a project scales, UI consistency becomes more difficult to maintain if a centralized source of design elements is not set in place. No matter how subtle the differences are, inconsistent widget sizes or colors become more apparent and user satisfaction inevitably declines.

The concept of a design system is simple: define the basic UI building blocks for your product or brand in one central location, and reference them from anywhere in your codebase. By sticking to a system, clients or designers can maintain visual styles in one place, making it effortless for developers to implement beautiful UIs throughout the application.

For more info on the benefits of using a design system, take a look at this great article by supernova.io, a design system app built with Flutter.

Available Rules

# copy these contents to sidecar.yaml at
includes:
  - "lib/**.dart"

lints:
  design_system_lints:
    rules:
      box_constraints:
      box_shadow:
      color:
      edge_insets:
      icon:
      radius:
      text_style:
      theme_data:
        # additionally, severity for each rule can be set to
        # either: info, warning, or error
        severity: warning

Setup

  1. Add design_system_lints as a dev_dependency and design_system_annotations as a regular dependency to your app's pubspec:
name: example_app

environment:
  sdk: ">=2.18.0 <3.0.0"

dependencies:
  design_system_annotations: ^0.1.0
  flutter:
    sdk: flutter

dev_dependencies:
  design_system_lints: ^0.1.0
  1. Create a sidecar.yaml file and add the rules you want to enable for your codebase:
# sidecar.yaml
includes:
  - "lib/**.dart"

lints:
  design_system_lints:
    rules:
      icon:
      box_constraints:
      text_style:
      radius:
      box_shadow:
      edge_insets:
      color:
      theme_data:
        # severity for each rule can be set to
        # either: info, warning, or error
        severity: info
  1. Finally, enable the sidecar plugin in analysis_options.yaml at the root of your project so that the lints can run in your IDE:
# analysis_options.yaml
analyzer:
  plugins:
    - sidecar

To learn more about using rules in your project (including CLI), follow the usage guide over at sidecaranalyzer.dev.

Usage

Once the rules are enabled, the lints are designed to show info messages wherever design system rules are not properly followed. For example, the edge_insets rule enforces a standard usage of padding and margins by locating EdgeInsets code that uses sizes defined outside of a design system.

import 'package:flutter/material.dart';

final large = 12.0;

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      // appears for hardcoded integer or double values
      padding: EdgeInsets.only(left: 11.0, right: 9.0), // lint: edge_insets

      // also appears when using variables that are declared
      // outside of a design system
      margin: EdgeInsets.all(large), // lint: edge_insets
    );
  }
}

Instead of using any variable for your padding, which is hard to maintain as your application scales, its better to define sizing by either using static variables.

The package design_system_annotations allows you to annotate your size variables with @designSystem, and permits their use throughout your codebase.

import 'package:design_system_annotations/design_system_annotations.dart';
import 'package:flutter/material.dart';

// create your design system values
// the below values happen to follow the concept of an 8pt scale
// see: https://medium.com/swlh/the-comprehensive-8pt-grid-guide-aa16ff402179
@designSystem
class DesignSystem {
  static const xsmall = 2.0;
  static const small = 4.0;
  static const medium = 8.0;
  static const large = 12.0;
  static const xlarge = 16.0;

  static const primary = Color(0x02569B);
  static const secondary = Color(0x12B9FD);
}

// use the design system anywhere throughout your codebase
class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: DesignSystem.primary, // no lint
      padding: EdgeInsets.all(DesignSystem.large), // no lint
    );
  }
}

The above design system was defined using whats known as the 8pt system, which just about guarantees a consistent and perfectly flexible UI in your Flutter app.

Enforcing use of a highly maintainable UI system is as easy as that!

You can additionally use design_system_lints to enforce many different types of parameters, including SizedBox and Container height and width values, Color values, Icon values, and more.

Further resources

Sidecar is a new package that allows anyone to create custom rules for their codebase. Since custom rules are a relatively new concept, further questions and feedback are expected. We encourage you to join the conversation on discord and follow the sidecar project.

design_system_lints's People

Contributors

pattobrien avatar

Stargazers

HuynhToan avatar Arnold Lumangtad Jr. avatar Lucas SAUDON avatar sowiner avatar Hugo Heneault avatar Toan Nguyen Truong avatar Pierre Sabbagh avatar Teddy avatar Nguyễn Hoàng Ân avatar  avatar Nikita Sirovskiy avatar Till Friebe avatar Matthew Jaoudi avatar Miki Oracle avatar Roscoe avatar  avatar Kazunori Ninomiya avatar Seif Almotaz Bellah avatar Seiya Kokushi avatar Roman Proshin avatar  avatar

Watchers

 avatar

design_system_lints's Issues

Strict Enforcement of Material Theme

Design system elements are more powerful when used together with proper Theming in a Flutter app. If developers simply use static properties like Color throughout a codebase, then those UI elements will not dynamically update on theme changes: for example, if a user switches from dark to light mode.

Enforcing strict usage of Themes throughout a codebase is necessary for these cases. Additionally, we'll need to consider use cases such as defining Theme extensions for custom Widgets (e.g MyPrimaryButton).

Text themes specifically are more prone to inline editing (e.g. adding boldness to a particular Text widget). We will need to understand if there's a non-inline way of modifying themes.

Another potential problem is that Material Theme has many fallback themes, in case one is not explicitly specified at the Widget or App levels. If we have an off-white in our design system, but we don't use that off-white anywhere in our App theme, do we throw a lint if a Text widget uses a white from the default Material Theme and not the off-white from our design system? We need to understand the inner workings of Theme and Material's fallback themes to come up with a sustainable solution.

Multiple plugin warning and Theme. of(context) usage

First of all, thanks for the work. Great package

So I have encountered two issues:

  1. I noticed that when I added the sidecar plugin, I received a warning stating, "Multiple plugins cannot be enabled"(I'm also using dart_code_metrics). Have you encountered this issue before and do you know how to resolve it? (Please refer to the attached image for reference.)
    image

  2. In cases where I use Theme.of(context).colorScheme and textTheme, how can I apply these in the design_system_lint? (Please refer to the attached image for reference.)

image

This is my implementation of the design system:
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.