Skip to content

Conversation

@JonasBa
Copy link
Member

@JonasBa JonasBa commented Jul 14, 2022

This is a proof of concept PR that is not meant to be merged, I created it as a showcase on how leveraging composition can help reduce API surface and increase flexibility of the codebase.

The changes in the PR are the following

  • removal of showPermalink boolean prop
  • creating a PermalinkTitle component
  • passing a PermalinkTitle or Title component based on what used to be showPermalink

With the changes introduced here, you can see that we have removed one prop from the component while simultaneously also exposed the api of PermalinkTitle which was previously inaccessible to the consumer, meaning we can now independently pass custom props to each instance of the PermalinkTitle component without having to extend the API of our TraceEvent component and avoid prop drilling entirely.

To summarize the functional benefits:

  • You are no longer limited to Title or PermalinkTitle - you can pass whatever component you like
  • Exposes PermalinkTitle meaning you can pass different props to each instance however you please to without extending/adding new props
  • Reduced API surface (1 prop removed)

In an ideal scenario, the PermalinkTitle would have been a core UI library component so as to avoid creating new custom components around the codebase and the Title component would not have included any margins by default so that we would not have to override them.

Some resources:

@JonasBa JonasBa requested a review from a team July 14, 2022 21:24
@github-actions github-actions bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Jul 14, 2022
Copy link
Member

@markstory markstory left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason you don't want to merge this? It looks like a positive change to me.

@JonasBa
Copy link
Member Author

JonasBa commented Jul 15, 2022

@markstory I havent really verified that it works exactly as before (that margin 0 is missing for instance), was mostly meant to demonstrate what I meant

justify-content: flex-start;
:hover ${StyledIconAnchor} {
&:hover ${StyledIconAnchor} {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please, what is the difference between &:hover and :hover?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

& is a stand in for the parent. It's specifically less/sass, it will compile to something like

.Perma-c1273 {
  display: inline-flex;
  justify-content: flex-start;
  ...
}

.Perma-c1273:hover {
  display: block;
  ...
}

I hadn't thought much about it before, but that it works with just :hover in emotion is kind of weird, it's probably some emotion-specific shorthand, which imo for one character we probably shouldn't be doing.

tldr; I agree with Jonas replacing it here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@k-fish I actually replaced it thinking that it is broken and that it probably doesn't compile correctly 😅

Copy link
Member

@priscilawebdev priscilawebdev Jul 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, I see... can we enforce this through eslint, so we can have everywhere the same pattern? and thanks for the explanation @k-fish 🙏

@priscilawebdev
Copy link
Member

I like the idea too, but before we can merge it, we have to make sure that everything is according to the previous styles.

Great PoC @JonasBa! Thanks for sharing this 👏

Copy link
Member

@k-fish k-fish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice 👍, I agree about shipping it as an example (if it's not too much work to fix styles)

Comment on lines 267 to 280
interface PermalinkTitleProps
extends React.DetailedHTMLProps<
AnchorHTMLAttributes<HTMLAnchorElement>,
HTMLAnchorElement
> {}

export function PermalinkTitle(props: PermalinkTitleProps) {
return (
<Permalink href={'#' + props.type} className="permalink" {...props}>
<StyledIconAnchor />
{t('Stack Trace')}
</Permalink>
);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, nice example Jonas 👏 . I usually call this specialization as per https://reactjs.org/docs/composition-vs-inheritance.html, I've heard it called it a number of names in both eng side and design (used to call it 'molecules' in an atom-based design system).

Definitely one of the patterns I reach for the most since you can have the ease-of-use of a simple api / use for common "combinations" of more generic underlying components.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes 💯 you explained this perfectly, I was not really sure how to call it. I might have read that and just forgot about it

justify-content: flex-start;
:hover ${StyledIconAnchor} {
&:hover ${StyledIconAnchor} {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

& is a stand in for the parent. It's specifically less/sass, it will compile to something like

.Perma-c1273 {
  display: inline-flex;
  justify-content: flex-start;
  ...
}

.Perma-c1273:hover {
  display: block;
  ...
}

I hadn't thought much about it before, but that it works with just :hover in emotion is kind of weird, it's probably some emotion-specific shorthand, which imo for one character we probably shouldn't be doing.

tldr; I agree with Jonas replacing it here.

@JonasBa
Copy link
Member Author

JonasBa commented Jul 21, 2022

@priscilawebdev let me know if you would have 10min to spare to pair on this PR and wrap it up. It's a bit hard for me to assert everything works as intended.

@priscilawebdev
Copy link
Member

@JonasBa is this still a draft PR?

@JonasBa JonasBa marked this pull request as ready for review August 1, 2022 12:47
@JonasBa JonasBa requested a review from a team as a code owner August 1, 2022 12:47
@JonasBa
Copy link
Member Author

JonasBa commented Aug 1, 2022

@priscilawebdev nope, I hadn't noticed I left it as a draft. It should be good to go, I'd appreciate if you can give it another look to make sure I haven't missed anything

Copy link
Member

@priscilawebdev priscilawebdev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checked locally and it looks good to me

stackTraceNotFound: boolean;
stackType: STACK_TYPE;
title: React.ReactNode;
title: React.ReactElement<any, any>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did we change this because it can be null or undefined?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it because you cant cloneElement on null/undefined and it didnt look like null/undefined is intended usage.

@JonasBa JonasBa merged commit cd457a6 into master Aug 3, 2022
@JonasBa JonasBa deleted the jb/poc/composition branch August 3, 2022 13:23
@github-actions github-actions bot locked and limited conversation to collaborators Aug 19, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants