typestyle / typestyle

Making CSS Typesafe 🌹

Home Page:https://typestyle.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

named style sheet - thoughts on pull request?

jeremy-coleman opened this issue · comments

I added this to the typestyle class, allowing for improved stylesheet debugging
(maybe there's already an easier way to do this?)

I'll send a pull request if you'd like , after any feedback.

this snippet is inserted directly below the current stylesheet function

imo a separate function is appropriate instead of extending the current stylesheet.

  defaultOptions = {
    name: "tss"
  }

  // Wrapper for the typestyle style function that ignores the name parameter.
  public namedStyle = (name: string, ...objects: NestedCSSProperties[]) => this.style(...objects);

  public makeStylesheet = <Names extends string = any>(classes: CSSClasses<Names>, sheetOptions?): CSSClassNames<Names> => {
    //office ui fabric uses scope instead of name - this bit needs some work
    if(sheetOptions && sheetOptions.scope) {sheetOptions.name = sheetOptions.scope}
    let options = { ...this.defaultOptions, ...sheetOptions}

    const classNames = Object.getOwnPropertyNames(classes) as (Names)[];
    const result = {} as CSSClassNames<Names>;
    for (let className of classNames) {
      const classDef = classes[className] as NestedCSSProperties
      if (classDef) {
        classDef.$debugName = `${options.name}-${className}`
        result[className] = this.style(classDef);
      }
    }
    return result;
  }

image

source just uses optional name / scope option, like this

export const MuiButtonStylesheet = makeStylesheet({
    root: {
      display: "flex",
  },
  {name: "MuiAppBar"}
);

Being able to specify a string that becomes part of the class name would be awesome. Would make it quite a bit easier to trace styles back to their declaration when debugging (comparing properties is quite tedious).

I think style could be given another overload to support an optional string as the first parameter, which is how I'd like to see this work there. Usage of reflection grab the string to form part of the class name in stylesheet sounds like a good approach as well, though I'm not sure what the best way to implement it would be (seems wrong to just change the default behaviour).

The nameStyle function isnt used as a standalone in the code above, but accepts as its first argument a string for the classname of an individial rule its just style() with the name param spread out of it. I think name must come second though for the stylesheet, as its an optional feature and would be breaking otherwise. For the name from function alone, i think a babel macro would be easiest , and second choice is to change stylesheet to a class so there is a always a constructor.name prop available , but that is also breaking. File paths are also unique , which is a pretty good option

Hmm. Lots of ways to go about this. I'm sure there are ways to make this backwards compatible without hindering usability though.

I'm not to sure about using file paths as a source of uniqueness though. Would only really work fine in Node without any bundling.

This looks useful.

Currently in my react applications I have been using typestyle with class-to-component and inject-display-name.macro which helps with debugging a lot.

What you are proposing would be a more generic solution.

commented

I don't think there is a reason to make a second stylesheet function in TypeStyle: (see stylesheet on https://typestyle.github.io/#/core) The typical way that options are configured in TypeStyle is by adding $ properties. I think it would be interesting to add $debugName to stylesheet and use that as an additional prefix for each className and I believe it would solve for your use case.

WDYT?

I agree no real need for a second function, i was advocating for making it an optional second arg on a new function just in the off chance it had some unforseen consequences for existing users(i am of the opinion that you should practically never have a breaking change). As for debug name, i think thats a good option , but i think the primary use case here is for deterministic style names for library authors (ie: in the production build), So maybe $debugName should remain dev only? How about $prefix or $component?

It has occurred to me that when I was last looking at this ticket I overlooked that $debugName is a thing. 🤦 Support for attaching a name to the overall stylesheet would be handy. Implementation wise I can see this as;

Optional string as first arg

import { stylesheet } from "typestyle";
const className = stylesheet("identifiable-debug-name", {
    fooBar: { color: "black" },
}); 

Make $debugName have special meaning (technically would require a semver major release)

import { stylesheet } from "typestyle";
const className = stylesheet({
    $debugName: "identifiable-debug-name",
    fooBar: { color: "black" },
});

The latter could be a more natural fit with the existing API in my opinion. Would be worth formalising $... properties as being ignored if such a change were made though, should additional options be considered in the future.