datopian / datahub

🌀 Rapidly build rich data portals using a modern frontend framework
https://www.portaljs.org
MIT License
2.2k stars 328 forks source link

Feature Request: Add className Property to Components in the Library #1037

Open mohamedsalem401 opened 1 year ago

mohamedsalem401 commented 1 year ago

I would like to request the addition of a className property to the components in the library. This property would allow users to easily apply custom CSS classes to components, enabling greater flexibility in styling and customization.

Use Case:

<Excel className="w-full" />
<LineChart
     className="h-5"
/>

Why It's Needed: Currently, the components have limited customization options, making it challenging for users to adapt the library to their specific design requirements. By adding a className property, users can apply their own styles without having to override the component's default styles, providing a more seamless and flexible experience.

Implementation Details: I propose adding a className property to each component, which would accept a string of CSS classes. This property should be merged with the component's existing classes to ensure that it works seamlessly with the library's styling.

mohamedsalem401 commented 1 year ago

I can complete this task within a few hours if you believe it's ok to proceed.

rufuspollock commented 1 year ago

@mohamedsalem401 really clear need. My question is what is best practice for "headless" components here - that would be the optimal way to proceed.

Otherwise a backup is using the className approach you describe.

rufuspollock commented 4 months ago

@demenech what do you think?

demenech commented 4 months ago

@demenech what do you think?

I like it, this is a very common feature among component libraries.

The way this is proposed is a good start, it's very annoying to not be able to control the sizings of the components easily, my only concern is that customization still wouldn't be that flexible.

E.g.

function MyTable({ className }) {
  return <div className={`${className}`}> {/* <== Note className is being applied here */}
    <h1>This is my table</h1>
    <table>
        {/* ... */}
    </table>
  </div>
}

Note that in the example above, users can customize the wrapper, but the heading and other children are still pretty much static.

On the other hand, combined with plain CSS classes it could become more flexible:

// Styles
.my-table-custom-styling h1 {
  color: red;
}

// Render component with specific className
<MyTable className="my-table-custom-styling" />

I'm just wondering if there are better ways to implement it.

Possible solution (haven't thought much about this):

function MyTable({ className, nestedClassName = { h1: "" , table: ""} }) {
  return <div className={`${className}`}> {/* <== Note className is being applied here */}
    <h1 className={nestedClassName.h1}>This is my table</h1> {/* <== For relevant children items, have an unique id */}
    <table className={nestedClassName.table}>
        {/* ... */}
    </table>
  </div>
}