-
Notifications
You must be signed in to change notification settings - Fork 536
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Propose a new file structure (ADR) #1678
Conversation
|
size-limit report 📦
|
Having a consistent file structure would also lay the groundwork for us to create a |
Questions I would like to settle in this ADR: | ||
|
||
- On subcomponents: | ||
- Do subcomponents filenames need to be namespaced with the parent component? (e.g., `BreadCrumbsItem.tsx` vs `Item.tsx`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
➕ : Makes searching for related files easier in the IDE
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have to say first - super happy to go with what the majority of the team prefers. very loosely help opinions.
Aw, I was going to vote ➖ on this because it is scoped inside the component folder: src/Breadcrumb/Item.tsx
.
For example, in VS Code, i would search for "action item" to look for ActionList/Item
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, I prefer the longer more descriptive name.
|
||
- On subcomponents: | ||
- Do subcomponents filenames need to be namespaced with the parent component? (e.g., `BreadCrumbsItem.tsx` vs `Item.tsx`) | ||
- Should the `index.ts` in each component directory export every subcomponent under its own name, or should we prefer `Object.assign`ing subcomponents to the parent component? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could it depend on whether the subcomponent is private to its parent and not intended for composition? I.e. With a compound component, I'd expect it the parent component to be the only one exported from the folder. Might be misunderstanding this point though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I've seen two different styles:
BreadCrumbsItem
, which isn't exported on their own and is only accessed asBreadCrumbs.Item
ButtonDanger
, which is available as its own export.
it is reasonable to me that those are different, asBreadCrumbsItem
only makes sense as a child ofBreadCrumbs
.... and maybe we could name that as a rule? Alternately, we could consolidate to one style, right?
- Do subcomponents filenames need to be namespaced with the parent component? (e.g., `BreadCrumbsItem.tsx` vs `Item.tsx`) | ||
- Should the `index.ts` in each component directory export every subcomponent under its own name, or should we prefer `Object.assign`ing subcomponents to the parent component? | ||
- Should subcomponents always have their own test files? What about type tests and stories? | ||
- Would this structure help if we wanted to move toward one-package-per-component like react-aria does? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This approach totally opens doors to this and makes codesplitting much easier to maintain. Big ➕
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that makes sense — personally I don't know enough about what makes tree shaking possible or not possible to be confident that separate packages are actually necessary.
Pretty hyped for this. It'll improve the experience across the board, for both contributors and consumers. Thanks for proposing it @jfuchs. |
- Should the `index.ts` in each component directory export every subcomponent under its own name, or should we prefer `Object.assign`ing subcomponents to the parent component? | ||
- Should subcomponents always have their own test files? What about type tests and stories? | ||
- Would this structure help if we wanted to move toward one-package-per-component like react-aria does? | ||
- Could we set a standard for replacement components? E.g., NewButton vs. Button2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my personal vote is for src/drafts/Button
or even src/drafts/Button2
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohh interesting — can you say more about why you like that?
I hesitate because it'd mean advancing the status of a component from propsed -> alpha would have to be a breaking change, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hesitate because it'd mean advancing the status of a component from proposed -> alpha would have to be a breaking change, right?
Don't think so. we should use drafts
for replacement components which can be at a more advanced maturity than their current counterpart. For example, ActionList v1 is alpha but ActionList v2 can be at beta maturity while being in drafts. This is why we chose drafts over other names. More context here: #1609 (comment)
I like it more because it matches the bundle scope. drafts
are not part of the main index.js bundle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love it! ship it!
- On subcomponents: | ||
- Do subcomponents filenames need to be namespaced with the parent component? (e.g., `BreadCrumbsItem.tsx` vs `Item.tsx`) | ||
- Should the `index.ts` in each component directory export every subcomponent under its own name, or should we prefer `Object.assign`ing subcomponents to the parent component? | ||
- Should subcomponents always have their own test files? What about type tests and stories? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so. There are going to be subcomponents that rely on some context to get passed down from the parent.
210e268
to
d902f45
Compare
|
||
- Every component should have its own PascalCased directory directly under `src/` | ||
- Subcomponents meant to be used as children of their parent component should be properties of the exported component (e.g., `BreadCrumbs.Item`) | ||
- Subcomponents meant to be used on their own should be exported as a named export (e.g., `ButtonDanger`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a pattern we want to encourage?
I'd argue that it's not a "subcomponent" if it's exported on its own. If it's not a property of a parent component, I think it should probably have it's own directory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like simple rules.... but thinking about that with ButtonDanger
.... that doesn't feel like it merits its own component, and I'm not sure I'd want that to just be a prop on Button (i.e., <Button variant="danger"...
). Would you say ButtonDanger
should have its own directory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I'd want that to just be a prop on Button (i.e., <Button variant="danger"...)
FYI ButtonDanger
is going away in favor of a variant
prop. @pksjce's Button2
uses that API.
I don't think we plan to have any components like ButtonDanger
in the future
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay cool. That settles it then :-)
### Rules | ||
|
||
- Every component should have its own PascalCased directory directly under `src/` | ||
- Subcomponents meant to be used as children of their parent component should be properties of the exported component (e.g., `BreadCrumbs.Item`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean that the Object.assign
happens in Breadcrumbs.tsx
or index.tsx
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't mean to specify — but if you think this should I'm fine with that!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can add more rules to this doc as we form opinions. So I guess it's fine to be vague now.
IMO, the Object.assign
should happen in Breadcrumbs.tsx
. index.tsx
seems mostly like an implementation detail to make imports nicer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should index.tsx export default or named?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. I lean towards named export. In general, I'm not a big fan of default exports (unless they're necessary for some reason)
Co-authored-by: Cole Bemis <colebemis@github.com>
04d6620
to
6696d1e
Compare
Co-authored-by: Cole Bemis <colebemis@github.com>
* Proposes a new file structure (ADR) * Update contributor-docs/adrs/adr-XXX-file-structure.md Co-authored-by: Cole Bemis <colebemis@github.com> * More questions about the implementation process * Doc updates; removal of open questions * BreadCrumbs -> Breadcrumbs * Remove note about separately exported subcomponents * Update contributor-docs/adrs/adr-XXX-file-structure.md Co-authored-by: Cole Bemis <colebemis@github.com> Co-authored-by: Cole Bemis <colebemis@github.com>
This PR adds a proposed ADR establishing a file convention.
There are two reasons I'm doing this:
Merge checklist
Take a look at the What we look for in reviews section of the contributing guidelines for more information on how we review PRs.