My company is using Angular for web development. Fabric looks great, but you just support React. If you implemented your components as web components they could be consumed easily by both React and Angular (and a ton of other frameworks).
I think web components is the way to go for anything UI related.
Look at https://stenciljs.com/ for a cool system for creating components with Typescript.
FWIW, Fabric is actually entirely consumable (with some work) from within other frameworks like Angular and Knockout. But you do pay the price of having to have the code of multiple frameworks being loaded.
I'll let @dzearing comment on your primary feedback though.
@RaulRG is right. I had this same discussion with my team 3 weeks ago about ui-fabric. Pigeon-holing developers into React and MergeStyles guarantees obsolescence while a WebComponent implementation would obviate the need for any framework when used on a WebComponents-capable browser and only polyfills for all others. This provides forward compatibility for years (maybe even a decade) and ensures the largest possible audience for UI Fabric.
WebComponents are the way of the future for the web and the way of the Jedi for developers.
On another note, running 2 UI frameworks side by side represents an unacceptable risk in the vast majority of projects due to maintainability and DevOps complexities not to mention the huge overhead added on startup.
Thumbs up for web components.
Please!
I'd love to use this with Angular.
Just to clarify, my comment above is just providing a "FWIW" and is not meant to represent Fabric's official POV/recommendation. I know of actual product teams using Fabric React components hosted within a Knockout app, and @KyleMcNutt at the last WebDev meetup, demonstrated Fabric React components being used in an Angular 2 app (in his talk "Stop Bickering - The Web is Winning").
Again, this is just a data point and not meant to represent Fabric's official position.
Tagging @KyleMcNutt. His slide deck for the talk he gave is at
http://slides.com/kylemcnutt/deck-1#/
If I can help out just let me know
Even if web components are the way of the future, we still have to support a wide browser matrix. With a polyfill required just to make things work on IE11, Edge, and Firefox let alone mobile browsers, I'd worry about bundle size and runtime perf getting a hit on these platforms. I'd love to drop IE11 support, but unfortunately this is still a huge chunk of traffic in enterprise scenarios. That's why at least picking a framework now and creating components on top of that gets us to a place where we can focus on more holistic problems that works well with the framework.
I also want to call out there are a number of other scenarios to solve that require some opinion on the underlying tech to make things work. For example, we need SOME css in js framework to enable theming correctly (something we're investing heavily in right now.) One might argue that you could get by with just css and css variables. But again, browser matrix... and contextual scenarios. and color computation scenarios.
I don't want to downplay web components, and I'd love to take advantage of this, but we need to have some sort of traction on building out components that partners can take advantage of now, on the majority of browsers, without a lot of polyfill dependencies required by the host. And, we have pretty limited resources here, so the investments really need to be targeted.
That all said, we are very open to contributions. If we set up an experimental playground, would someone be willing to help drive the experiment? It would be interesting to have someone port a fabric component to web components as an example that could be replicated if it's successful. There are a number of things I'd be curious about:
Random team uses %framework of choice%. How does this integrate into their framework? Is this just as efficient as writing against the native framework, or would you make sacrifices? For example, would a React application rendering web components need to do anything special here? (e.g. shouldComponentUpdate = false to prevent React from messing with the underlying dom) How do we enforce partners use the right polyfill to support the browsers without full web component support?
And how would a perfect css solution in this world look? Is there really some alternative agnostic solution here that works with the variety of scenarios we need? (Themability, css modules, ssr, etc.) I have heard a LOT of opinions about this, and trying to make everyone happy is just not going to happen (use fela, no use emotion, no use styled-components, no write a separate css file with variables, no I like sass... what about that new css library by random product team?)
Let us know what a good path going forward might be! Happy to empower contirbutors to try things here; we can set up a seperate package that can get published as a v0 so that we can evaluate things like bundle size, usability, perf, etc. codepen examples...
While not a solution, but more of a "workaround", we developed a package that can render React components inside Angular. Similar packages have existed before, and even referenced in this repo on another issue, but they are unmaintained, and I'm not sure they are still working with Angular 6.1 (latest version as of writing this).
We developed angular-react, a library that does something similar, and I feel it's mature enough to be used in production (we've been using it in our customer-facing up for the last few months, which is based on Angular 6.1. I also know of at least one other team that are in the process of onboarding it for use in their app).
This should cover most use cases, since office-ui-fabric-react
covers React, and using @angular-react/fabric
you can get the same components in an Angular application.
Vue is also on the rise, and something similar can probably be done for it using something like vuera. It should be easier than the Angular case since both use a VDOM.
One obvious disadvantage of this though is that you'd have to include react
and react-dom
(in addition to office-ui-fabric-react
) in your final bundle, but we decided that was an OK price to pay.
This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 5 days. It will be closed if no further activity occurs within 3 days of this comment. Thank you for your contributions to Fabric React!
Excuse me for not giving you feedback. I thought everything was said. It seemed to me that you would not go the web components path and so it was not an option for us. Everything what you said about browser compatibility and polyfills is right, but there are libraries for building the web components that take care of the polyfills, but if you need to support IE then it is probably a problem. It is a shame, we think fabric could be great for us, but we don't want to go react for it.
Web Components are poo. And I've noticed it's mostly angular developers pushing for web components. If web components are the best w3c or whatwg (or whatever the hell the standards body is these days) can come up with, then we're already in strife.
I don't agree with you. Look at this site: https://custom-elements-everywhere.com/
As you can see Angular, Vue, Svelte support them 100%. React is lagging behind, but it will change over the next months. For me is the idea of using the platform, and the browsers will get better and better on web components. I don't know if it is the best possible implementation for components, but it is the current direction.
I am not interested on an Angular vs React debate, it just happens that I am using Angular at work.
https://reactjs.org/docs/web-components.html.
You've really just started the debate yourself by creating an issue titled as such. Anyway, looks like folk, far smarter than myself, have got some different approaches for you. Make sure you stick rigidly to those standards ;)
Let me talk amongst the community to get a sense of what this could look like.
Let's do this:
My concerns are primarily that our limited resources spending as much time making the component library as accessible, as customizable/theme-able, as react-friendly, as intuitive as possible, is the right investment. There are a lot of rough edges we want to iron out.
Switching gears on all of that to support web components might be perceived as a longer term investment, but I think it comes with tradeoffs:
How will it perform in React? (Is there overhead in mounting 1000+ components in web-components wrapped in React wrappers vs native react? What scales to production web apps? Are there performance benefits in web components at all? (e.g. perhaps there is less dom diffing.)
How do non web-components work with them? (e.g. can I still inject react content in a web component's children?
If someone has insight, and more importantly can prototype an example we can play with (in a codepen or sandbox?) that would be really helpful.
Experimented with StencilJS in December and love the results, with some minor concerns.
Still concerned with IE11 support and performance in large quantities. Needs more experimentation, more so with performance.
We will keep this issue open, and potentially start some experimental packages which port a set of the components to a web components package produced through stencil.
This sounds very good!! Keep us informed, please. For us IE11 is not an issue as we already decided to drop support for it. The limitations are too big to use anything "modern", but I understand if it is a requirement for fabric.
Just to throw out another approach. I decided to play around with Angular Elements, which takes Angular Components and creates a Web Component out of it (with some additional bridging), and it yielded good results in general.
I basically created Angular Components that wrap the Fabric React Components, then used Angular Elements to output that into a Web Component. I can then include that output on any HTML page, as just a <script>
tag, and the Component's work!
Advantages: This would mostly have IE11 support, with the right polyfills in place. There are some features of Angular that don't seem to work as Angular Elements on IE11 (specifically Native View Encapsulation). But, I don't think that matter in this case, because we already have that implemented in the React layer.
Disadvantages: Pretty big bundle size, as well as multiple layers of frameworks to possibly cause perf issues, though in some initial perf testing it's actually doing much better than I thought.
@dzearing Sorry for the ping; what's the progress on this? I'd love to use the fabric components but I can't switch my company's projects to react. I'd love to contribute, and not invest time into my own take on a port to stencil web components. I'm sure that if there was an official project on github people would contribute!
Stencil was just an example of something that could be used. There are other possibilities like LitElement from Google / Polymer ( https://lit-element.polymer-project.org/ ). As @KyleMcNutt wrote, Angular Elements is another one, but probably too big bundles as today. It is supposed to get better when the Ivy renderer is finished someday.
I just think that Fabric is too important to just be constrained to a given framework.
@johannes-z @RaulRG thanks for the ping! We are just as excited about the possibility of supporting more than react through web components. Also very excited about css variables!
The short term update is that because we need to still support IE11, we'll be focused primarily on addressing top issues in our current set of things for at least the next 4 months. That said, especially due to the major updates coming to Edge, ditching IE11 support seems like it could be a reality much sooner. That'd give us the option to take advantage of modern APIs.
I've started weeding out some of the problems we'll need answers for in a few example sandboxes.
Some of the issues we need to tackle:
How should callbacks work (e.g. a component which has an onChange, or multiple onClicks... now we are dealing with imperative API, rather than React's declarative form.)
Styling. If we are using shadow dom, the styling approach needs to change (I believe) as the shadow dom is unaffected by styles registered in the global domain. I tried rendering our Button in a web component using shadow dom, and the styled didn't work. (avoiding shadow dom fixed it.) Or at least that was my observation.
Slots in web components don't seem to have a functional input => content
approach, so consuming state provided by the container seems non intuitive. For example, a disabled SpinButton
should likely tell the upButton
and downButton
slots to also be disabled. In our slots work in React, this is doable. In web components, slots are dummy boxes with no input to base off. So we will need to understand that one...
There is still no state management solution. There is still no dom updating solution. These are really fundamental in building reusable components. An imperative appendChild
approach feels light years behind vitual dom approaches. So we either use scaffolding on top like stencil or other solutions, or we roll another thing. Ideally, we wouldn't do either, and these problems would have native solutions. We've started some discussions with the Edge team about what's needed here and what's coming.
If we just wrapped out existing components in web component wrappers, it would be a REALLY chunky bundle. But even if we were to be ok with that, there are so many things that are messy. For example we'd need to abstract how props flow from a raw html element to the inner react component. Just reading a boolean flag would require a getAttribute
call and a cast and assignment. Maybe we could have some general helpers to lower the cost of doing that, but it's expensive and bulky and pretty much doomed to not be good enough size-wise for production apps.
Have any of you used a web component library that you liked to build an app? What was good about the model? How would you want to pass along state to them, and how would you want callbacks to work? Coming from years of imperative api development to React's declarative approach and back, it all seems like going backwards in time to me. Would love to hear what "good" web components look like.
More food for thought; React's support for web components has some issues at the moment:
https://custom-elements-everywhere.com/libraries/react/results/results.html
Some of these could add friction for React apps using the components. I'm sure it's temporary, need to dig around more for status on this.
@dzearing Those are some valid points, that obviously only really come apparent when you play around with (native) web components more. I tried stenciljs (just because I didn't know anything else), and I really liked it: there are a lot of similarities to react, vue and angular and kinda feels like a mixture of those libraries.
I created a showcase repo (https://github.com/johannes-z/fabric-ui-stencil). It's a vary naive approach though, and I just copied CSS styles from the office ui fabric react documentation without fiddling around with that too much.
Here are my point of views on the question you raised:
When using stenciljs, they polyfill everything for you. Even shadow DOM falls back to scoped styles if the browser doesn't support it. React surely also has to polyfill (Object.assign, Promise, stuff like that); so it's not about performance or bundle size.
I'd also argue that stenciljs' bundle size is going to be smaller than a full react, react-dom + polyfill solution.
I haven't played around much with exposing events from the web component to a consuming app. The way stenciljs handles events is (almost?) identical to how vue.js handles it, using DOM events. I've done a lot of projects using vue.js, and never thought its event system is bad... on the contrary, I was more put off by react's synthetic events.
The styling approach definetly needs to change using web components. I'd say it changes for the better though. In my example it's super easy to at least override the theming of web components. I'm not sure about override entire styles (e.g. border size and stuff like this (basically what you now pass in with the style
prop for react)).
As a side note: I tried porting the react components to vue, and reverse engineered the styled
/merge-styles
using @uifabric/utilities
and @uifabric/styling
approach: It's very hard for new commers to understand what's going on, and feels very cumbersome as well. This is not necessary using shadow DOM.
My example doesn't use slot, but as I understood it you can always pass props down to children as well. In your example, I guess passing the disabled
prop to the children (upButton
) would fix this issue.
Ok I'm not sure if I understand this a 100%. With stenciljs this doesn't seem to be a problem, since props/state is reactive.
I don't see any reason not to use a web component building framework (stenciljs, polymer, vue, angular, not sure about react?). It's not like opting in on a frontend framework such as react. It just helps bundling, polyfilling, and abstracting away technical layers that a developer shouldn't need to worry about.
If you created an official project that pursues the implementation of Fabric as web components, with official reviewers/maintainers, a lot of work could be done already in parallel to the react implementation. As of now, all the fabric react forks/ports are a one-man show and thus incomplete and/or old. I at least am really eager in contributing to a fabric web component project, but I won't start one...
Let me know what you think!
Thank you @johannes-z !! A much more competent answer than anything that I could say. I don't do any web development, but one of our teams uses Angular and would like to use Fabric. This is not possible as long as it is React-only. This was the reason for my request.
Yeah @johannes-z thanks for the writeup.
Couple of followups;
We're playing with options on the "how", including how contracts might look, how the dom stays updated, and how the code is organized (which might be dependent on results from the varying framework investigates.) fyi @kenotron
Still many concerns to weed out within the context of each framework:
Perf (what is the runtime overhead, bundle size overhead.)
SSR (how would this work)
Versioning (if you register the same component name twice, you get an error... this could be a major blocker for scenarios which require 2 copies of a library on the same page.)
More food for thought; React's support for web components has some issues at the moment:
https://custom-elements-everywhere.com/libraries/react/results/results.html
Some of these could add friction for React apps using the components.
Would just like to add that, although I obviously get where this concern is coming from, it does highlight a major motivation to get this working:
Right now, Fabric is a luxury for React users. Only those who choose to use React, get to use Fabric. Which actually stops a bunch of users who just want to use Fabric.
I'm not even an advocate for web components in particular, I'd just like to highlight that anything decouples Fabric from React is a major win in my opinion and will benefit a bunch of users who are being left out at the moment.
I've just come across direflow which aims to create web components using react. Based on its lifecycle, it seems similar to angular-react except that it is framework agnostic.
Has anyone tried using this out before?
+1 to web components
Most helpful comment
Experimented with StencilJS in December and love the results, with some minor concerns.
Still concerned with IE11 support and performance in large quantities. Needs more experimentation, more so with performance.
We will keep this issue open, and potentially start some experimental packages which port a set of the components to a web components package produced through stencil.