-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
RFC: Support for Fluent UI contrib packages #27480
base: master
Are you sure you want to change the base?
Conversation
This RFC lays out the architectural requirements that will need to be finalized to be able to support non-core components in the Fluent UI umbrella. Once enough feedback has been collected the RFC will be updated to include the final decision
📊 Bundle size report🤖 This report was generated against f0b05741d812ad90c52754b0b4035d5554cf2aa0 |
Asset size changesSize Auditor did not detect a change in bundle size for any component! Baseline commit: f0b05741d812ad90c52754b0b4035d5554cf2aa0 (build) |
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 3280c49:
|
Co-authored-by: Miroslav Stastny <[email protected]>
Co-authored-by: Miroslav Stastny <[email protected]>
Co-authored-by: Miroslav Stastny <[email protected]>
- 👎 Manage the infra for another domain and publish | ||
- 👎 Needs work to support independently versioned packages | ||
|
||
### Parnter ownership and collaboration |
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.
### Parnter ownership and collaboration | |
### Partner ownership and collaboration |
This is great Ling! My two cents - coming from 4+ years of working on a fluent extension library. We know most consumers of fluent consume it through an extension library, so better supporting that story is a win for everyone. I think there are a lot of benefits to having the extension component packages living in the same repo. I see a bunch of benefits:
As far as breaking changes go, I do think these extension components have a tendency to break more often (for good reason) so we should plan for that. What worked well for us in admin-controls:
Something we'll want to weigh the pros and cons for on a monorepo approach is the cost of breaking changes in core fluent. I think the core team will have to assume responsibility for upgrading all the extension packages when we decide to break. This is good in that all those extensions will stay current, and it forces us to empathize with consumers when we're making breaking changes. Bad in that we'll hesitate more when making breaking changes that we probably should. Incentivizes us to shepherd best practices in contributions. One issue we'd run into was ownership. An enthusiastic engineer might spend 2-3 months contributing a component from their app, and then (due to circumstances outside their control) not be able to support it going forward. Core team members would then have to assume responsibility for a component that was architected inconsistently with the rest of the library. Handling that learning curve is hard and requires a LOT of training and documentation on our part. Most of out contributors were surprised and frustrated by how much time it took compared to when they wrote it in their product. I don't really have a great solution for this yet. Really really strong conformance tests? The other untapped potential we have is theme tooling, creation and hosting. Admin-controls ended up being sought after for teams to go create their fluent themes because we'd optimized around that task. Many of those consumers/contributors weren't even using admin-controls. Most only needed slight tweaks to an existing theme. The result was a library of themes that many teams benefitted from. I also think we need to consider cleaning up the fluent repo to make this successful. It has grown a TON over the years and I'm not sure all the packages are relevant to it's core mission. Having both v8 and v9 in the same branch confuses searching. |
We create components that will not be shipped as a part of our 'core' components under the `@fluentui/react-components` | ||
library but other packages. We will have to finalize the following requirements: | ||
|
||
- Should non-core components be able to deviate from V9 core concepts? |
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 yes. they will be owned by other teams, we should give them trust to make the right decisions. they might need to opt out of compliance checks.
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.
define 'deviate'...are we talking about slots, or file structure, or styling or what.
I think there is a good question here as to 'how much can a component deviate from the v9 concepts while still being at all related to v9'
If I write a quick (props)=> <div>{props.children}</div>
is this a fluent ui component as long as it matches a design somewhere in a figma?
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 we should try to be too restrictive here for non-core components. For non-core, I'd even propose that no one needs our permission to call something part of the Fluent ecosystem.
I do think, however, there are some guidelines.
- It should follow the Fluent design guidelines
- It should depend on the Fluent/v9 core SDK, which means respecting design tokens
- It should not re-invent existing primitives, but it may not depend on any primitives
library but other packages. We will have to finalize the following requirements: | ||
|
||
- Should non-core components be able to deviate from V9 core concepts? | ||
- Should non-core components have a faster breaking change cadence? |
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 yes, they should be versioned independently. They should have a peer dependency on core components.
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.
in Fluent AI (copilot) we are building sub 1.0 controls, so we can break going from 0.2.0 to 0.3.0
I think there is still value in moving towards a stable release and using semver properly, but I could see some extended control sitting at 0.215.1 for a while
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.
If scenario where fluent extension adhere to fluent core standards, based on recent discussions there should be no breaking changes ( breaking changes may/will happen after particular major bumps - removal of APIs etc ).
We already started go 1.0 route within core so that should probably be followed. Ideally this will also drive us to establish fluent core which will be used within react-components suite and extensions.
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.
Our breaking change policy for core/v9 is highly restrictive, for the reason that primitives that everyone builds on and builds shared experience based on needs to be highly stable. I would not expect any other teams to follow it, and if we don't need to follow it for higher-level experiences we should not restrict ourselves to it (but also remember that it's very important for primitives, or components that other teams build on heavily).
I think the leaf nodes, and non-core components could, and honestly should, have breaking changes more often. They should, of course, follow semver. And whether it's 0.x.y or x.y.z versioning they should follow semver and rev appropriate when they have breaking changes.
- Should non-core components live in a separate repo? | ||
- Should non-core components still be under the `@fluentui` scope? | ||
- How should users consume non-core packages? | ||
- How should non-core components be documented? |
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.
preferably in storybook, which can be federated with core storybook.
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.
storybook is not the best public documentation kinda of thing. might be good opportunity to explore something more robust and nicely polished like docusaurus/astro - also I assume those extensions should be part of official Fluent docsite we are building right (having storybook is a serious performance pain )?
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 would +1 not using storybook for public documentation if there is scope - it was built as a playground experience and has been co-opted into docsites. We have been using it for acs ui library and it got us of the ground fast, but we've found it limiting, clunky and hacky to get it to a good state.
That said, whatever Fluent sticks with should be what is available in the infrastructure package by default for others. So to me this is tangential to this RFC and a question on if Fluent are sticking with Storybook in the long term.
Thanks for writing this up, this is an increasingly important thing to consider as v9 is adopted more broadly. Below are my thoughts and preferences for each section outlined in the RFC:
|
library but other packages. We will have to finalize the following requirements: | ||
|
||
- Should non-core components be able to deviate from V9 core concepts? | ||
- Should non-core components have a faster breaking change cadence? |
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.
If scenario where fluent extension adhere to fluent core standards, based on recent discussions there should be no breaking changes ( breaking changes may/will happen after particular major bumps - removal of APIs etc ).
We already started go 1.0 route within core so that should probably be followed. Ideally this will also drive us to establish fluent core which will be used within react-components suite and extensions.
|
||
- Should non-core components be able to deviate from V9 core concepts? | ||
- Should non-core components have a faster breaking change cadence? | ||
- Should non-core components live in a separate repo? |
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.
no silver bullet here, it depends :)
- Should non-core components live in a separate repo? | ||
- Should non-core components still be under the `@fluentui` scope? | ||
- How should users consume non-core packages? | ||
- How should non-core components be documented? |
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.
storybook is not the best public documentation kinda of thing. might be good opportunity to explore something more robust and nicely polished like docusaurus/astro - also I assume those extensions should be part of official Fluent docsite we are building right (having storybook is a serious performance pain )?
|
||
#### @fluentui scope | ||
|
||
Non-core packages would be published under the same `@fluentui/` NPM scope. |
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.
yes
|
||
#### New package scope | ||
|
||
Creates a new package scope, `@fluentui-banana/` (name pending) for all components/packages that are non-core. |
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.
new scope might make sense only when its out of FUI domain - eg system that builds on core controlls but provides completely different UI
|
||
#### Current monorepo | ||
|
||
Non-core packages should still live in the monorepo. |
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.
extensions that adhere to FUI family should live within one monorepo.
- 👎 Our partners might still want to customize to the max | ||
- 👎 Approaches could be heavily biased on a subset of partners | ||
|
||
### Breaking change cadence |
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.
- breaking changes in none FUI family extensions can happen as their maintainer need
- breaking changes in FUI family extensions if possible, should adopt patterns we "plan" to adopt within core -> major version bump is not really a breaking as we maintain old apis and remove those after particular major bumps or defined time period
Appreciate this great write-up @ling1726 @layershifter 🙌 Besides in code comments I'd like to add some things and share my POV on this topic. Based on the convo and content of this RFC we should probably differentiate extensions into 2 categories:
to elaborate on this FUI family extension
non FUI family extension
|
@ling1726 owns this RFC on behalf of @microsoft/teams-prg |
@khmakoto owns this RFC on behalf of @microsoft/cxe-red |
I think there is one higher level consideration that I'm curious about which I think may need resolution prior to landing the implementation details and considerations outlined in this PR. One of the side-effects of opening up the Fluent repo to include contributions from Fluent partners is how the design and API considerations get resolved when there are either competing implementations or competing requirements. Something being under the Fluent UI umbrella implies that it is the "blessed" implementation. What is the working model for determining the "base" implementation of what ends up in the Fluent repository and the breadth of it's API? Consider a scenario where two teams have a similar The above is a quick example, but I think the larger question of how we determine what gets hoisted into the "blessed" implementation is key to this discussion and a resolution. For instance, if the goal isn't to have a single "blessed" implementation of If there's an answer to this already, I'd love to see it guide this discussion! I might have missed it, but it seems like some of the questions raised within this RFC could be more easily resolved with clarity around this. |
Adding to @chrisdholt's comments, I also see this RFC will affect more than just v9's decisions. The answers to the RFC are at the heart of how Fluent UI thinks about components, determines component boundaries, and how we define of a "Fluent" component. This also touches the scaling strategy for including more products in publishing, maintaining, and discovering Fluent UI components across the company. There are some historical decisions that have been made and are operating by assumption and default right now. We probably need to refresh and document those. I've listed some of them below. I plan to make a trip to Redmond soon so our US folks can collab in person. We can do some earlier US mornings to catch Prague evenings as well. In no particular order, some important guiding statements for Fluent UI today (that we need to explain, document, and build from):
This is a short, top of mind, list of the direction we're currently pursuing. It is also not exhaustive. Apologies for not giving the context, constraints, and reasoning behind each but this comment would be pages long. That is what I propose we do when we get together to formulate a solution to this RFC. I'm also really looking forward to that. |
@levithomason thanks for the feedback, looking forward to working to get more context around these decisions so we can come to a concrete working solution.
These points are already encapsulated in one of the proposals of this RFC - create a separate repo for extension packages and publish them under a different scope. I've taken the approach to let us keep some kind of link to these 'conformant' extension packages. This will make sure that we are in a position to give guidance to partners who might not have the experience that this team has with creating reusable components and also formalizes a 'conformant' implementation for customers so that there is a boundary of trust there. I'd like to know your thoughts on that.
This seems to me like contributors should host their own code, but we own the distribution vector? This is not encapsulated by the RFC and I'd like to incorporate it once I know more about the context behind this. Looking forward to discuss further.
Yes storybook composition is also proposed in this RFC, however @Hotell has shown some reservations there.
Agreed, I'll incorporate this in to the RFC
I've mentioned the need to deviate from core principals in this RFC. I'm not sure how we could go about formalizing other design models especially as requirements for 'conformant' implementations are expected to vary based on specific needs. Let's discuss this further |
@chrisdholt That's a really good point. I've updated the RFC to add a clear position on this but here is the short version.
I would like to keep the position that the core team should be a guiding influence, and not an extra requirement on these teams. However, it's perfectly reasonable to build on the work of others, so we should have an elevation process to the 'blessed' implemetation WDYT? |
- build | ||
- type check | ||
- linting | ||
- unt tests |
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.
- unt tests | |
- unit tests |
@ling1726 Thanks for the replies. We're in agreement. There is much to discuss in detail and document and we will do that, maybe next week. We'll set up some time with you and @Hotell. I'd like to formalize something like 3 or 4 consumer groups (users + use cases) for Fluent UI. I believe the dimensions that define each consumer group are something like:
These dimensions drive the decisions about the component model and distribution model. Example, the Fluent UI core library primarily serves the "1st party, high reuse, maximum customization" consumer group which drives a different set of needs than HVCs which are primarily "1st/2nd party, lower reuse, min customization". Once we formally document these groups (already implicitly defined in OKRs and such), we can then assign the right Fluent UI Conformance criteria to each group. Our current conformance tests, which need updating, are targeted only at the Fluent UI core consumer group and isn't useful in its current form for what we're discussing here. I think this is now where your RFC lands, it is asking for answers which will solve the above. What is the Fluent UI Conformance criteria which we will use to service all our consumer groups? How do we define it? How do we manage conformance? How do we handle contribution and distribution for each group? I think we first start with defining our consumer groups, then the criteria for each, then we can map all our current work and efforts around implementation to these needs. Really looking forward to this 😄 |
|
||
#### Self code hosting | ||
|
||
Code for `@fluentui/contrib` packages should be self hosted. The Fluent UI team will provide bootstraping utilities |
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.
Will these bootstrapping utilities have an update path? If Fluent improves the pipelines/storybook/etc. can we ensure downstream bootstrappers can easily update to get new behavior also?
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.
Yes it's what is mentioned with the intention to use NX to work on these bootstrapping utilities, since the tool supports migrations which can be run when upgrading
Noting that I met with @ling1726 and @miroslavstastny on this topic in depth. @ling1726 will be posting an update to propose 3 or more package scopes for us to release components to. Each scope will serve a certain customer need and component model requirement. Details to follow. |
This RFC lays out the architectural requirements that will need to be finalized to be able to support non-core components in the Fluent UI umbrella. Once enough feedback has been collected the RFC will be updated to include the final decision
PREVIEW