suitcss / suit

Style tools for UI components
http://suitcss.github.io/
3.81k stars 229 forks source link

What's the naming convention for local components? #172

Open Sam-Kruglov opened 1 month ago

Sam-Kruglov commented 1 month ago

What if I have a LocalComponent that's not intended for use outside of MyComponent - how do I name CSS classes? Would that be ok?

export default function MyComponent(..) {
  return <MyComponent className="MyComponent">
  <ul className="MyComponent-localComponents"> ----- plural name for the descendant
     <LocalComponent/> -- for loop here
  </ul>
</MyComponent>
}

function LocalComponent(..) {
  // can't use "LocalComponent" because that's ambiguous
  // could use MyComponentLocalComponent but that's too long 
  return <li className="MyComponent_LocalComponent">
  <AnotherLocalComponentInfo/>
  <form className="MyComponent_LocalComponent-form">...</form>
</li>
}

function AnotherLocalComponentInfo(..) {
  return <div className="MyComponent_LocalComponent_AnotherLocalComponentInfo">
  <Image className="MyComponent_LocalComponent_AnotherLocalComponentInfo-logo"/>
  ...
</div>

I'm using the underscored name for the descendant but I have to overwrite the Stylelint regexp:

componentName: /^[A-Z][a-zA-Z0-9]+$/,

to ^[A-Z][a-zA-Z0-9]+(_[A-Z][a-zA-Z0-9]+)*$

It feels a little off but I think it's ok. I didn't find any docs on that use case, just wanted to confirm.

Sam-Kruglov commented 1 month ago

In this case we have 1-1 of SUIT Component to React Component even private ones. You could say I'm depending on implementation details and should only use MyComponent as SUIT Component but it's CSS, of course it's super tightly coupled anyway, if I decide to get rid of AnotherLocalComponentInfo, my CSS will definitely break no matter what..

Sam-Kruglov commented 1 month ago

Another edge case is that a local component returned a <p> tag, so there is no wrapper, so I don't have a CSS class Main_Local but I do have Main_Local_text

Sam-Kruglov commented 1 month ago

Now that I've configured everything, it looks like I either have to add comments to each CSS class or use one component per CSS file, so for the example above, I'd need MyComponent.css and MyComponent_LocalComponent.css.

So, I'm going with mashing the local component names into descendant names:

.MyComponent {...}

.MyComponent-localComponent {..}

.MyComponent-localComponentForm {..}

.MyComponent-localComponentAnotherLocalComponentInfo {..}

.MyComponent-localComponentAnotherLocalComponentInfoLogo {..}

But the preferred solution would be that the componentName supplied to componentSelectors function would be the the part of CSS class that matches componentName regexp instead of file name.

Another workaround would be to create separate CSS files for local components and import all the CSS files into the MyComponent.tsx but I don't like the clutter, so I'm going with the above

Sam-Kruglov commented 1 month ago

Another issue that is possibly a bug: if I define multiple components within one file via comments, the file name is still validated. I think as soon as I use comments, file name should not matter, e.g. I got fallback.css with Loading, Failed, FailedMany.

Workaround - rename file to Fallback.css but that introduces a confusion as if I have a component named Fallback which I don't, so I keep fallback.tsx as is.