Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UI] Token-based approach for interface elements and colors #13735

Open
wants to merge 30 commits into
base: 5.x
Choose a base branch
from

Conversation

andersonjeccel
Copy link
Contributor

@andersonjeccel andersonjeccel commented May 8, 2024

Q A
Bug fix? (use the a.b branch) [ ]
New feature/enhancement? (use the a.x branch) [X]
Deprecations? [ ]
BC breaks? (use the c.x branch) [ ]
Automated tests included? [ ]
Related user documentation PR URL mautic/mautic-documentation#...
Related developer documentation PR URL mautic/developer-documentation#...
Issue(s) addressed Fixes #...

Description:

This PR adds a different approach to handle interface elements. Its main focus is to make sure we don't have a carnival of colors everywhere, making the development process easier, faster and understandable.

It's only a technical addition like happened with the Remix icon pack, no breaking changes.

I'll talk about:

  • What are tokens?
  • Covered elements
  • But why to use them?
  • Light and dark theme
  • Buttons hierarchy
  • Automatic brand palette
  • Accessibility features
  • Moving all Bootstrap variables into CoreBundle

What are tokens?

Tokens are nothing more than a set of predefined values which we can use to create consistent interfaces.
In this case, the tokens will act as CSS variables, so we can use them as the value of elements' properties, such as a background or text color.

They also:

  • Make easier to apply brand colors, that's useful for our stakeholders
  • Ensure we have a beautifully constructed interface if brand customization is disabled, using Mautic brand instead

Covered elements

Absolutely everything can follow this standard. We have specific subsets of colors like Backgrounds, Buttons or Links which suits all of our needs.

Let's take layers as an example.
On the interface, the thing at the bottom is the page background. So the body will have its background-color set to --background:

body {
background-color: var(--background);      // It'll be white
}

But then you want to put a widget on it. Well, you'll have to use the Layers subset. So, your new widget will have its background color as --layer:

.dashboard .widget {
background-color: var(--layer);    // A light gray
}

What happens if you need to put a new layer on the layer? Just add an alternate layer.

.dashboard .widget .something-useful-on-top {
background-color: var(--layer-alt);    // It becomes white again
}

Look this image to understand visually how it works:

image

But why to use them?

  • It's easier to use when compared to the initial LESS solution, because lighten and darken functions can be so customizable that you just lose track of things
  • The set is built previously considering all use scenarios; it means that you have enough flexibility to never run out of options but still maintaining consistency
  • Thanks to god, it becomes easier to fix problems; if someday our need for contrast change, for example, you have a solution in less than 20 seconds

Light and dark theme

This PR adds a light and a dark theme. Mautic will follow the user's operational system (or browser) settings to automatically show the adequate theme based on their preferences.
Since this implementation uses CSS variables, we can create (later) a toggle for dark/light theme. For this to happen, we need to ask the browser to change prefers-color-scheme to light or dark.


Buttons hierarchy

The set of colors already consider the need for buttons hierarchy: primary, secondary, tertiary, ghost, icon-only, inverse, hover, active, focus, everything.

It’s a key part of designing interfaces because it guides users through the system naturally. Think of it like a newspaper; the most important news story gets the biggest, boldest headline and is placed at the top of the page. Less critical stories have smaller headlines and are placed further down.

In this idea, buttons work similarly:

Primary buttons grab attention for the main actions you can take. Secondary and tertiary buttons are more low-key, so you know they’re not the main focus. Then there are special buttons like “ghost” buttons, which are subtle, danger buttons that warn you, or icon-only buttons that save space but still tell you what they do. This mix of buttons helps users quickly figure out where to click and what each click will do, making the whole experience smoother and less confusing.


Brand center

We're introducing a concept of brand center, where you can change a few lines of code which rules the entire brand customisation.

Automatic brand palette

All a brand needs are hue and saturation from its main color.

Taking Mautic as an example:

Hex #4e5e9e
RGB rgb(78, 94, 158)
HSL hsl(228, 34%, 46%)

Convert your HEX color to HSL then save the hue and saturation, the key values that create a brand color.

Then you can fill:

// Brand center --------------------------------
:root {
    --brand-color-hue: 228;
    --brand-color-saturation: 34%;
}
// ----------------------------------------------- 

Magical code will convert your brand's color to adequate UI colors for buttons, links, interactive elements, colored icons and anything that's naturally colored on the interface.


Accessibility features

The new code ensures that, if people do not want transparency, animations, transitions, motion in general, and their operational system or browser is set to ask websites for this, these items will be disabled.

If people want more contrast, they can also ask the platform to use borders on buttons and other elements (again, having this enabled on OS or browser).

(someone can create toggles for these later)


Moving all Bootstrap variables into CoreBundle

I needed to do this because it'll become easier to improve consistency in next PRs, and solve the variables being imported 5x when generating the CSS files.

Steps to test this PR:

  1. Open this PR on Gitpod or pull down for testing locally (see docs on testing PRs here)
  2. Hover over buttons and links to see a new transition duration
  3. Check if labels are present on Channels > Emails list (you have to have a few created)
  4. You can also do the same testing of this one because it uses the token library to work
  5. No more tests since this PR aims to only add technical resources and organize tokens from previous PRs :)

New features are being built on top of this code (see my last PRs).

@andersonjeccel andersonjeccel self-assigned this May 8, 2024
@andersonjeccel andersonjeccel added T1 Low difficulty to fix (issue) or test (PR) feature A new feature for inclusion in minor or major releases bug Issues or PR's relating to bugs user-interface Anything related to appearance, layout, and interactivity ready-to-test PR's that are ready to test code-review-needed PR's that require a code review before merging enhancement Any improvement to an existing feature or functionality developer-experience Anything related to developer experience labels May 8, 2024
@andersonjeccel andersonjeccel added this to the 5.2 milestone May 8, 2024
@andersonjeccel andersonjeccel requested review from LordRembo, a team and ricfreire May 8, 2024 17:55
@andersonjeccel andersonjeccel force-pushed the ui-token-based-approach-for-interface-elements-and-colors branch from d994160 to c7d151b Compare May 8, 2024 20:03
@LordRembo
Copy link
Contributor

@andersonjeccel Maybe we can discuss this in our meeting next week. I'm not quite following what still needs to be done for the JS part but we can see then.

@andersonjeccel
Copy link
Contributor Author

andersonjeccel commented May 19, 2024

Pending tasks

  • Add typography sizes
  • Add secondary color palette
  • Create --background-brand-primary and --background-brand-secondary

Copy link

codecov bot commented May 20, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 61.93%. Comparing base (a66c8d0) to head (179c312).
Report is 4 commits behind head on 5.x.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##                5.x   #13735      +/-   ##
============================================
+ Coverage     61.88%   61.93%   +0.04%     
- Complexity    34193    34195       +2     
============================================
  Files          2248     2248              
  Lines        102258   102265       +7     
============================================
+ Hits          63287    63336      +49     
+ Misses        38971    38929      -42     

see 9 files with indirect coverage changes

@andersonjeccel andersonjeccel force-pushed the ui-token-based-approach-for-interface-elements-and-colors branch from 2f28f6d to 6cdf195 Compare May 21, 2024 16:47
@LordRembo
Copy link
Contributor

On the surface, these changes make sense to me: Getting rid of imports for variables if they are already loaded elsewhere or replaced.
One thing I'm not seeing though: there is a this line that is added to the mixins, but I don't see it being used anywhere: .background-blur(), where is that used?

@andersonjeccel
Copy link
Contributor Author

@LordRembo Decided later to create classes in the pull requests when they're used, so you're right about it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issues or PR's relating to bugs code-review-needed PR's that require a code review before merging developer-experience Anything related to developer experience enhancement Any improvement to an existing feature or functionality feature A new feature for inclusion in minor or major releases ready-to-test PR's that are ready to test T1 Low difficulty to fix (issue) or test (PR) user-interface Anything related to appearance, layout, and interactivity
Projects
Status: ⏳︎ Needs 1 more test
Status: In Progress
Development

Successfully merging this pull request may close these issues.

None yet

4 participants