Skip to content
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

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
322 changes: 322 additions & 0 deletions rfcs/react-components/non-core-components.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,322 @@
# RFC: Support for components in the Fluent UI umbrella that are not core

[@ling1726](https://github.com/ling1726)

## Summary

@fluentui/react-components has matured, with many flexible primitives that are also highly customizable. These
primitive components generally don't reuse each other and are considered the 'building blocks' of a design system.
Future design iterations might introduce components that are either:

- Very situational - i.e. applied to specific scenarios only
- Composed of multiple primitive components
- Specializations of primitive components

We need to formalize the how we will deliver these components not only as first party packages but also second party
packages with our partners who might need more situational components powered by V9. This RFC refers to these kinds
of components as `non-core`.

## Problem statement

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?
Copy link
Contributor

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.

Copy link
Member

@micahgodbolt micahgodbolt Apr 24, 2023

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?

Copy link
Collaborator

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

- Should non-core components have a faster breaking change cadence?
Copy link
Contributor

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.

Copy link
Member

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

Copy link
Contributor

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.

Copy link
Collaborator

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?
Copy link
Member

Choose a reason for hiding this comment

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

yes
even if it is just to allow those controls to use their own semver and not have to jump up to 9.0.0-rc217

Copy link
Contributor

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 still be under the `@fluentui` scope?
- How should users consume non-core packages?
- How should non-core components be documented?
Copy link
Contributor

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.

Copy link
Contributor

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 )?

Copy link
Member

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.

- How should code for partner owned components be hosted?

The Proposal treats each of the above questions separately and provides pros/cons for different approaches we could take.
Keep in mind that some decisions will influence other decisions.

None of the approaches are particularly complex to understand, but the resulting work could be complex. It is important
that we figure out what answers for these questions so that we can start to move forward
with technical implementation by following concrete requirements.

## Detailed Design or Proposal

### Deviating from v9 core concepts

It's difficult to formalize what 'deviating' means here, and any attempt to do so will probably not be
very future proof as the library continues to evolve. The main objective of this section to decide whether or not
we should allow deviations from v9 core concepts (whatever they are or might be in the future). Here are some
examples of current deviations that could happen based on the current situation:

- Allowing shorthand collections
- 'Fatter' JSX elements that have more functionality
- Less customizable styles
- More opinionated layout

The short list above indicates some possibilities to have components that are less flexible in cases where
components are more specialized versions of core primitives that we don't want to maintain a large customization
feature set for, or product/scenario specific components where we want more alignment across Microsoft.

The extent of 'deviating' will have to depend on the requirements of each component, but we should be ready to accept
that we might end up delivering a set of components that don't follow the principles that drive the core library
(@fluentui/react-components).

In cases where components need to deviate, we should notify the team through specs and architecture meetings
(i.e. tech sync), what deviations are done and the context behind them. All non-core components should still
follow the V9 spec driven approach.

#### Pros
Copy link
Member

Choose a reason for hiding this comment

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

i'm on team 'earned differences', where components should follow v9 approach (slots, hooks, child elements over render arrays) as much as possible. When users hit friction and want to deviate, we should discuss that friction and determine if that scenario is a valid earned difference, or maybe we just need better guidance, or a refined way to accomplish a goal.

example, user REALLY wants render arrays because that is what their customers are used to. Maybe we propose a way to create an exported function or hook that provides the same API while still leveraging the opt in/pay for play nature of v9.

Copy link
Member Author

Choose a reason for hiding this comment

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

That's a really good point, I've incorporated this to the RFC.


- 👍 Can enforce design across microsft more strictly
- 👍 Can be more flexible than core components
- 👍 Can be done on a case-by-case basis depending on requirements

#### Cons

- 👎 Can lead to a very inconsistent set of components that behave differently to each other
- 👎 Our partners might still want to customize to the max
- 👎 Approaches could be heavily biased on a subset of partners

### Breaking change cadence
Copy link
Contributor

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


#### Same cadence as core components

Breaking changes for non-core components will follow the same cadence as core components i.e.
breaking changes can only happen when @fluentui/react-components reaches v10.

##### Pros

- 👍 Predictability - nothing new compared to current library
- 👍 Good support for partners to build on

##### Cons

- 👎 Partners might not mind breaking changes for specialized components that are not used often
- 👎 Maintaining legacy for components that are not used often in applications

#### Faster than core components

Breaking changes for non-core components can occur more frequently than for core components. The proposal does not
mean that breaking changes will be taken lightly, or that there will be a requirement to make breaking changes often.

##### Pros

- 👍 Bleeding edge improvements for partners
- 👍 Specialized components might not have widespread use and can be upgraded in a few instances

##### Cons

- 👎 Cost of breaking changes has not changed
- 👎 Just because we make breaking changes does not mean users will upgrade earlier
- 👎 Need to handle urgent bugfixes for most past versions - need a clear support SLA

### Choosing a repo for

#### Current monorepo

Non-core packages should still live in the monorepo.
Copy link
Contributor

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.


##### Pros

- 👍 Easier setup
- 👍 Nothing new to learn
- 👍 Issue reporting path does not change

##### Cons

- 👎 We might not want the same release cadence - releasing a fix for a non-core component would release all of core
- 👎 Extra load on the CI as more non-core components are needed
- 👎 Not possible to have more separation from core components without lots of tooling hacks

#### Separate monorepo

We can create a new monorepo for our non-core packages and depend on core packages from NPM.

##### Pros

- 👍 We can have our ideal DX
- 👍 Release cadence does not need to depend on core
- 👍 Developing our with our public API - we eat our own dogfood
Copy link
Member

Choose a reason for hiding this comment

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

this is better than a single monorepo, but is this repo public? private? do we need 1 of each?


##### Cons

- 👎 Needs effort to setup
- 👎 Issue reporting becomes more unclear
- 👎 Requires linking to use latest core code
- 👎 Manual/Automated bumps required to keep packages up to date

### Package scope

#### @fluentui scope

Non-core packages would be published under the same `@fluentui/` NPM scope.
Copy link
Contributor

Choose a reason for hiding this comment

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

yes


##### Pros

- 👍 No need to create and manage another organization
- 👍 Easier discoverability for OSS users and internal partners

##### Cons

- 👎 Not clear that there is a difference between non-core components and core components/utilities
- 👎 Harder for us to tell the difference between non-core and core

#### New package scope

Creates a new package scope, `@fluentui-banana/` (name pending) for all components/packages that are core
or non-core.

##### Pros

- 👍 Very clear differentiation between core and non-core
- 👍 Creates a clear boundary for FUI team and partners to collaborate
- 👍 Clear path to upgrade/downgrade packages between core and non-core (i.e. experiments/compat)

##### Cons

- 👎 Need to maintain a new NPM organization and credentials
- 👎 Initially could cause some confusion if we don't communicate this well

### How users should consume components

We should keep the same architecture we currently have for our core components: one package per component. What should
be decided here is how users consume these components.

#### Suite packages

Structure non-core components into a new suite package similar to `@fluentui/react-components`.

##### Pros

- 👍 Similar to core components
- 👍 Easy to update when using multiple components

##### Cons

- 👎 Needs to follow the breaking change cadence of each components
- 👎 Slows down breaking changes for all components

#### Individual packages

Users should install each component package individually.

##### Pros

- 👍 Easy to pick and choose components that might not always be relevant
- 👍 Allows more flexible breaking change cadence

##### Cons

- 👎 Easier to install duplicate versions
- 👎 We might be encouraged to break too often

### How to depend on core components

#### Depend directly on components packages

Each non-core component should depend on the individual core components

##### Pros

- 👍 Users will always install the required core components

##### Cons

- 👎 Consumes core packages in a way we don't recommend other users
- 👎 Dependency graph could be hard to manage/track
- 👎 Internal API might become public

#### Depend on suite package is peer dependency

#### Pros

- 👍 No unnecessary depdencies - we expect users to have core suite package installed
- 👍 Other examples in OSS - Material UI/React all recommend peer dependencies
- 👍 Easy for users to consume as long as core does not break
- 👍 We test how 'complete' our public API is

#### Cons

- 👎 V10 upgrade could be unpleasant - need to check what range is supported for each package
- 👎 More of our internal API becomes public

### Documentation

Fluent UI production components should always be documented regardless of whether they are core/non-core components.
This section describes the ways to document non-core components.

#### Current docsite

Create a new section in our docsite explicitly for non-core components alongside core components.

##### Pros

- 👍 Existing infrastructure already setup
- 👍 Enforces consistent documentation approach

##### Cons

- 👎 Do we want to document non-core components in the same way?
Copy link
Member

Choose a reason for hiding this comment

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

how do we deal with private packages

Copy link
Member Author

Choose a reason for hiding this comment

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

that's also an interesting question - do we want private packages in the FUI family at all?

Copy link
Contributor

Choose a reason for hiding this comment

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

private package != FUI family , private packages defeats the main purpose of OSS extensions

- 👎 For separate repo, would need to think about how to consume stories
- 👎 Needs work to support independently versioned packages

#### New docsite

Creates a new docsite for non-core components that will be linked to the current docsite.

##### Pros

- 👍 It's not hard to link between docsites that share the same look and feel
- 👍 Clear boundary for users to distinguish core/non-core components
- 👍 Possible to change documentation approach

##### Cons

- 👎 Manage the infra for another domain and publish
- 👎 Needs work to support independently versioned packages

### Parnter ownership and collaboration
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
### Parnter ownership and collaboration
### Partner ownership and collaboration


Partner teams might want to build scenario/product specific components, with guidance and support from the Fluent UI
team. The Fluent UI team should have a say in the quality of the code that is shipped by partner teams under the
Fluent UI umbrella and work with them to establish these quality criteria and ownership. This section proposes
two different ways we should host partner code.

#### GitHub

##### Pros

- 👍 Get different organizations in microsoft directly involved in open source

##### Cons

- 👎 Access management and compliance boundaries will be complicated
- 👎 Figure out how to make sure partners maintain their projects properly

#### ADO mirroring

Partner teams can continue to host their code in respective ADO reponsitories and we host a mirror for their
code in GitHub so that it is visible in open source for issue reporting and third party contributions.

##### Pros

- 👍 Already done in open source - React does this
- 👍 Partners can stick to the tools they know but still have open source presence

##### Cons

- 👎 Complicated infra work
- 👎 Potentially less accountability for partner teams that do this

#### Both

We let partner teams decide how they would like to participate in creating official Fluent powere components.

##### Pros

- 👍 Everybody is happy and can have a presence in open source
- 👍 Maximum microsoft coverage for open source
- 👎 Figure out how to make sure partners maintain their projects properly

##### Cons

- 👎 Cons of both solutions
- 👎 More work
- 👎 Figure out how to make sure partners maintain their projects properly