question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

New feature: manipulate with className as a set, instead of a string

See original GitHub issue

The class attribute is somewhat similar to style attribute: it’s a string representation of a more sophisticated data structure. In the case of style it’s a CSSStyleDeclaration, which is a map. In the case class, it’s a proxy for the classList: DOMTokenList, which is basically a set.

I think it’d be pretty natural to treat class similar to style and would also reduce conflicts with web components, where a web component could set its own “internal” classes.

This is what it could look like:

<div class={['class1', 'class2', isOn ? 'class3' : '', isOn2 && 'class4']}>
  ...
</div>

It would work as following:

  1. The array is expected to have a set of strings. False-y values (empty strings, false, null, etc) will be removed from the array before processing.
  2. The new array state will be diffed against the new state and only the changed classes will be added/removed.
  3. The element.classList will be used to add/remove classes.

Here’s a little demo: https://codesandbox.io/s/9lx87xkqvo. It shows that updating the class via Preact currently overwrites classes the classes set by an emulated web component.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
marvinhagemeistercommented, Feb 28, 2019

This is a neat idea and something that can be easily implemented via the suggestions by @lukeed above, or as a runtime hook:

import { options } from "preact";

options.vnode = (vnode) => {
  let props = vnode.props;
  props.class = doSomething(props.class);
  return vnode;
}

Because it is so easy to shim this feature and users usually bring their own variant of classnames, clsx, etc it is very unlikely that something like that would be added back to core.

1reaction
wizzard0commented, Feb 20, 2019

this is interesting, though i’d vote for using object instead of a class, like

<a class={{...someClassesFromProps, class1: true, class2: isOn }}>...</a>

rationale: easier to compose classes from different sources, if you use a list there’s no way to clear a class, and with object it’s just a matter of a spread operator

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to dynamically add a class to manual class names?
You can either do this, normal JavaScript: className={'wrapper searchDiv ' + this.state.something}. or the string template version, ...
Read more >
How To Modify Attributes, Classes, and Styles in the DOM
In this tutorial, we will learn how to further alter the DOM by modifying styles, classes, and other attributes of HTML element nodes....
Read more >
Styles and classes - The Modern JavaScript Tutorial
JavaScript can modify both classes and style properties. ... className , it replaces the whole string of classes. Sometimes that's what we ...
Read more >
Element.className - Web APIs | MDN
A string variable representing the class or space-separated classes of the current element. Examples. const el = document.getElementById('item ...
Read more >
HTML DOM Element className Property - W3Schools
Property Values · The class name(s) of an element. Separate multiple classes with spaces, like "test demo". ; class, The class name(s) of...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found