lukeed/clsxPublic

A tiny (239B) utility for constructing `className` strings conditionally.

Is this library compatible with css-modules?

question
MI

mihanizm56 opened ยท

Trying replace classnames/bind with clsx - but no hash in my classname in element availiable ![image](https://user-images.githubusercontent.com/37120827/104309825-d56e0a00-54e3-11eb-9774-57c350d6b3e2.png) ![image](https://user-images.githubusercontent.com/37120827/104309867-e28af900-54e3-11eb-806b-6593de575c9f.png) ![image](https://user-images.githubusercontent.com/37120827/104309887-e9b20700-54e3-11eb-8833-8c085ea8248a.png)

  1. MI
    Author

    with classnames/bind ![image](https://user-images.githubusercontent.com/37120827/104309965-03ebe500-54e4-11eb-88fd-97514af7a6c5.png)

  2. TR

    @mihanizm56 But you just pass "Button" string to clsx instead classes imported from css module. What do you expect?

  3. mihanizm56mentioned5 years ago on GitHub

  4. mihanizm56subscribed5 years ago on GitHub

  5. MI
    Author

    > @mihanizm56 But you just pass "Button" string to clsx instead classes imported from css module. What do you expect?

    I understand that I need to use some kind of object to match string classname to css module classname. My question is about is there any build-in support like in classnames/bind ?

  6. mihanizm56mentioned5 years ago on GitHub

  7. mihanizm56subscribed5 years ago on GitHub

  8. lukeedadded label question5 years ago on GitHub

  9. LU

    All `classnames/bind` does is hold a reference to a `styles` object & then iterate the keys, using the truthy keys for value lookup.

    The short answer is yes โ€“ css modules is primarily what clsx is used for.

    Here is a `bind` function that you can use with `clsx` โ€“ although, just to reiterate, you do not need this (or `classnames/bind`) in order to use clsx/classnames with css modules... it's just a shortcut.

    ```js // Option 1 function bind(styles) { return function () { var i=0, tmp, out='';

    while (i < arguments.length) { if (tmp = clsx(arguments[i++])) { if (out) out += ' '; out += styles[tmp]; } }

    return out; } }

    // Option 2 function bind(styles) { return function () { var i=0, arr, out=''; var tmp = clsx.apply(0, arguments);

    if (tmp) { for (arr = tmp.split(' '); i < arr.length; i++) { if (out) out += ' '; out += styles[arr[i]]; } }

    return out; } }

    // ---

    import clsx from 'clsx';

    const styles = { foo: 'abc', bar: 'def', baz: 'xyz' };

    // Either option const cx = bind(styles);

    cx('foo', ['bar'], { baz: true }); //=> 'abc def xyz' ```

    Finally, this `bind` approach in general actually hurts performance & produces less-optimized bundles. RE: performance โ€“ You're doing more _runtime_ work to get to the same result. RE: output โ€“ Most build configurations are able to analyze your `styles` object and any `styles`-key references, allowing unused keys to be purged from the output. This approach _purposefully_ separates `styles` from its keys accessors, which means that none of these tools are able to derive the same conclusions.

    Hope that helps!

  10. lukeedclosed5 years ago on GitHub

  11. MI
    Author

    Thanks for your code, and thanks for the explanations! 1) As for performance This hurts only build time a bit 2) As for tooling to reduce class names. We use BEM and this is hurts when you are trying to connect namings without any classnames-bind approaches. Also we use microfrontends where you actually have a lot of physically splitted apps with styles and your bundlers dont know if the style used or not. Can you please provide the names of that tools?

  12. MI
    Author

    @lukeed What do you think about to include this utilite named "bind" into clsx?

  13. lukeedmentioned5 years ago on GitHub

  14. lukeedsubscribed5 years ago on GitHub

  15. LU

    I won't add this to the README because I discourage it.

    You do not gain anything with this approach โ€“ it's purely a shortcut so that the dev(s) can type fewer characters.

    The above example is identical to this:

    ```js clsx(styles.foo, [styles.bar], { [styles.baz]: true }); //=> 'abc def xyz'

    // (and of course, the simpler version) clsx(styles.foo, styles.bar, styles.baz); //=> 'abc def xyz' ```

    Your (1) is incorrect. There is 100% added _runtime_ cost. Your (2) can be done & powered by `clsx` on its own. No `bind` needed. Am not sure what tool names you're asking for

  16. MI
    Author

    If this module doesn't contain '/bind' util - it is not a drop-in replacement for classnames module :blush: Actually yes a "/bind" solution makes a runtime cost but a lot of people use it.

  17. LU

    Yes it is. `classnames/bind` is a submodule.