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.

[RFC] Component Overrides Standardization & Documentation

See original GitHub issue

Current State of Overrides API

We have a fairly powerful overrides API. However, I think there are two issues we need to address sooner rather than later.

  1. It is not clearly documented to the users and is not easily understood at each component’s level. I have received a few repeated questions from users about how to override parts of their components.

  2. There is a lack of standardization on how we approach overrides for components that re-use our other components. Do we expose a top-level override API for the entire component that’s re-used, and expect users to make granular overrides by writing their own layer on top, or do we expose all the granular overrides of the re-used component?

Documentation Issue & Proposal

Our overrides API could be used in two ways:

const overrides = {
  Root: ReactComponent
};
// OR
const overrides = {
  Root: {
    component: ReactComponent,
    props: {...}
    style: {...}
       // OR
    style: ({$theme /* and other presentational props */}) => {...}
  }
};

This is not documented as a general API that every component follows. We do document this for every component but it’s not obvious at first glance. There are also some test coverage concerns raised in the style: ({$theme}) => {...} approach (anon function declared inline).

Secondly, it’s not obvious which component the user should override to achieve a particular behavior. In the case of Pagination, we have the following overrides

overrides: {PrevButton, NextButton, DropdownContainer, DropdownMenu, DropdownButton}

How can the user know the difference between DropdownContainer and DropdownMenu and decide which one to override without 1) reading the source code or 2) trial and error.

And in the case of the Modal component, which exposes the following overrides:

overrides: {Root, Backdrop, Dialog, DialogContainer, Close}

I’m not able to immediately understand the role of Root, Dialog, DialogContainer in relation to one another from this.

This extends to all of our other components that use the overrides API. A subset of the overrides are obvious, Close, PrevButton, etc. but many are not.

In order to fully utilize this overrides API, the user must have a clear understanding of the DOM structure and what each sub-component does.

Proposal

  1. We need a high-level overrides API documentation with some examples of how it’s used.
  2. Standardize on some sub-components, like Root - i.e. always the outermost <div> of the component.
  3. Have an Overrides API section for each component’s RFC that describes the presentational responsibility of each sub-component.
  4. It would be great to have a visual layered description of the component made up of its subcomponent. I don’t know how to achieve this though.

Components Re-use & Overrides

Select, for example, currently uses Menu underneath. There is no way to override the entire Menu component at the top level. Pagination also uses Button, but its API only allows overriding of the BaseButton sub-component inside Button. It’s also gearing up to re-use Select entirely.

Should both of these components allow only top-level override of Menu, Button, and Select? Or should, say, Select continue to expose more granular override options. But what if the user wants to override parts of Menu that’s not exposed as an override by Select?

Proposal

  1. Allow only high-level override of re-used components at the top API. If the user wants to override the internals of those component, they can do so separately:
function CustomMenu() {
  return (
    <Menu
      overrides={{
        Option: {...}
      }}
    />
  );
}

function MyComponent() {
  return (
    <Select
      overrides={{
        Menu: CustomMenu
      }}
     />
  );
}
  1. Expose all overrides of the re-used component, and reconstruct the re-used component internally with those overrides. This would expand the override API of Select to include all the overrides offered by Menu, and expand all of Pagination overrides to include all the overrides offered by Select (which includes all the overrides of Menu and so on…).

Conclusion

I don’t have a clear answer to any of these. But I figured that with our components count increasing, it would be good to align on these issues, before we start building more complex components.

Thoughts?

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:3
  • Comments:11 (9 by maintainers)

github_iconTop GitHub Comments

2reactions
tlrobinsoncommented, May 2, 2019

Just wanted to chime in with my “overrides” implementation using hooks or higher-order components to eliminates all the manual prop spreading: https://github.com/tlrobinson/overrides

(caveat: I just hacked this together last night and haven’t used it for anything real yet. It’s possible I’m missing a reason why this is a terrible idea. The only downside I’ve come up with is the extra layer of wrapper components it introduces)

Arguable whether that’s better or worse than the flattened list. But it seems like the real benefit here is how much it simplifies the internal implementation:

FWIW I’ve implemented nested hooks without flattening. It’s very simple to implement and I think it’s better to be explicit. And overrides={{ Calender: { Month: ... } }} isn’t much more verbose than overrides={{ CalenderMonth: ... }}, for example.

0reactions
github-actions[bot]commented, Sep 14, 2019

This issue is stale because it has been open 30 days with no activity. If it’s still valid, please remove the stale label or comment on the issue, otherwise this ticket will be closed in 5 days

Read more comments on GitHub >

github_iconTop Results From Across the Web

RFC 3261 SIP: Session Initiation Protocol - IETF
This document specifies an Internet standards track protocol for the Internet community, and requests discussion and suggestions for improvements. Please refer ...
Read more >
RFC 7953
Status of This Memo This is an Internet Standards Track document. ... components to override others of Daboo & Douglass Standards Track [Page...
Read more >
Override component test actions
Change the testing properties of a particular page component using -specific HTML attributes.
Read more >
Extensible Markup Language (XML) 1.0 (Fifth Edition) - W3C
This edition supersedes the previous W3C Recommendation of 16 August ... document declaration, which may appear as a component of the XML ...
Read more >
Standard for The Internet Printing Protocol (IPP): Page Overrides
PWG will document the results of their work as open standards that define print related protocols, interfaces, data.
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