 Hi everybody. My name is Benny Powers. I'm from Jerusalem, Israel. And in my day job at Red Hat, I work on the digital experiences team under the marketing department and specializing in design systems and web components. So today I want to talk to you about our project Patternfly Elements, which is our upstream design system. And we'll talk a little bit about Red Hat Design System, which is the downstream project. What that means, we'll get into detail a little later on. So let's take a look. So what is a web component? Okay, if you've never heard of web components before. So already stretching back to the 90s, UI toolkits like Delphi had modeled their components, their UI systems based on components. The idea of a component is like a button. A button has text, it maybe has an icon, it has a color, maybe it has a state. Okay, so the idea of components where the state and the style and the design and the functionality and the behavior are all encapsulated inside the component. You can just, if you have a drag and drop editor or put it in your XML file, whatever. Okay, reusable objects with consistent UIs and APIs. The web lacked its own component model until about 2015, when a group of web browser engineers and web developers got together at Google and tried to plan out what was going to be the future of web development. The browser engineers asked the developers, what do you need in order to make better applications? They said, well, we need components. And the browser engineers said, well, how can we do this in a way that works for the web and with the web? And that project eventually became the Polymer project at Google, which was the initial attempt at defining a component model for the web that later went on to become the web component standards, which are standardized and shipped by every browser today. So there are four core technologies in web components. We have custom elements. A custom element is basically an HTML element that is defined by your JavaScript class. So, you know, like the video element has certain behaviors, it can have controls, it can have slots for sources and things like that. You can write your own class in JavaScript to say, what's a fancy video? What's a fancy input? And then you can associate that with a tag name. And then any time that tag name appears in your document, the web browser will instantiate that object on the DOM with your class. That's custom elements. Shadow DOM is sort of like the secret sauce of web components. That's what gives you the encapsulation. A shadow root is like an isolated subtree of the document that's visible on the screen. So don't get confused. It's not invisible, but it's isolated from the rest of the DOM, which means that the styles that you apply inside your shadow root don't leak out. Maybe you remember what it was like back with, like, JQuery widgets, before they even called them components. You'd put, like, you know, some fancy JQuery button widget on your page. And out of nowhere, it would break some other part of your page because the class names conflicted or the IDs conflicted. If you put those class names or IDs in your shadow root, they can't conflict with the rest of the document. We have the template element, which allows us to very efficiently copy pieces of DOM from one place to another. So I define my template once, and then the browser can very, very efficiently stamp it hundreds of times in the same document without having to parse that HTML again. And the way that web components are distributed today is through JavaScript modules, sometimes called ECMAScript modules. The standard inbuilt language module system that was shipped in 2015, and we're just now beginning to see more widespread adoption in the rest of the JavaScript ecosystem. So what can you build with web components? Well, you can actually build any sort of web project with web components. You can build whole dashboard-complicated single-page applications. You can build what they call today multi-page applications where, you know, you leverage the browser's inbuilt navigation and things like that. You can build reusable widgets like a video player or maybe like a comment form or something like that. You can build design systems, you know, red hat button. Stripe payment. Actually just yesterday, or just two days ago, Stripe the payments company released their new version of their widget. It's a web component. And you can progressively enhance your pages. So you can put your content in HTML, wrap parts of it in web components, and when JavaScript comes online, those parts will be upgraded by the web component that wraps them. So the advantages of web components are performance. Instead of running a JavaScript framework's component runtime that your users have to download onto their low-range Android device, particularly in the global south, where most people have low-powered Android devices. Instead of running your JavaScript code or your framework author's JavaScript code, the component model is written in Rust or C++ by browser engineers. Another benefit is interoperability. Because web components are HTML, they are HTML, so they work anywhere that HTML works. For example, one time I had to solve a problem in a leaflet map inside of a view application, and we needed to add some interactivity to the tooltip inside the leaflet map. But the problem was the framework only allowed us to send a string of HTML. We couldn't interact with the DOM nodes, we couldn't get a reference, we couldn't add it to our framework. So we wrapped the content in a web component, registered that web component with the browser, and oh, there comes our interactivity. Another benefit is future-proofing. Because web components are standards, they're standardized in the HTML and DOM specifications, your app is going to work years from now. It's like the Space Jam website all over again. It's tables all the way down. Well, your app can be web components all the way down, and instead of having to go through that framework churn every time, you have the option to update your implementing library, your implementing framework, but you don't have to. You could implement a new part of the page with a new framework and still have them interact via the HTML and DOM APIs with your old components. And for me, I think that, especially in a large organization, the main benefit is knowledge transfer. Train up web developers. Don't train up framework developers. Because that framework, it might be popular today, but it's not going to be around forever. Teach your developers how to work with the web the way it is. Okay, so sometimes people say, like, well, web components, nobody really uses them, they're not really a thing. Well, I'm here to tell you that, yes, in fact, web components are a thing today. I feel like I need to get rid of the Reddit logo and maybe replace it with another one this week. It's not such a... But yes, web components are in use all over the web. Okay, if you look at NPM download stats, you might get one idea of what web development is all about. But if you look at the page load stats on the Chrome user interface project, you'll see that the use of web component APIs has been consistently skyrocketing over years. More and more companies, more and more small startups are adopting web components, and I encourage you to do the same thing as well. Web components are here to stay. And in actual fact, this presentation is made using web components. All these slides are custom elements. So that brings us to design systems at Red Hat. So let's have a brief overview of the history of how design systems came to be at Red Hat and some of the problems we faced and how we decided to try and solve them. So back in 2012, there was really a design free for all. We had multiple different projects, multiple different properties, and they all had their own designers, design teams, design philosophies, design languages, and nothing was really consistent from a design perspective and certainly not from a technical perspective. So that's why in 2014, the first version of the pattern fly library was developed. It was a proof of concept built using Bootstrap. I'm sort of glossing over a lot of the history here. Okay, so feel free to correct me in the chat. I don't mind. Okay, and this was the first step at Red Hat to aligning on a design system, and the name pattern fly was chosen as sort of like a non-corporate or corporate agnostic name that could develop a community around it. A few years later, the Red Hat Elements Web Components project started as the first attempt at a component-based design system here at Red Hat. It was a parallel effort to pattern fly. In 2018, the pattern fly team decided to double down on the React framework, and that was a sensible decision at the time because most of their users were, at least most of the users that they were interacting with regularly, by users I mean consumers of the library, like developers of pages and apps, most of those users were using React. So it made sense to focus on the framework that most people were using. Even if that did mean, yes, they were going to cut out use cases that were not using React. It was React or nothing. If you wanted a pattern fly, it had to be React. Okay, so the pattern fly React project elaborated on the Bootstrap MVP. It was mostly focused towards application development, like dashboards, SPAs, that kind of thing, but like we said, only for React. Shortly thereafter, the first edition of pattern fly elements came out, and this was an initiative in the marketing department in digital experience because for several reasons. First of all, we weren't using React, and we weren't going to use React. We weren't building SPAs, we were building landing pages for marketing sites and that kind of thing, and page loading performance is extremely important. And this was the first version of PFE was sort of a parallel effort with divergent UI needs. We weren't building towards application development, web app development, we were building towards web page development. So the UI patterns and the UI idioms were slightly different. This created a situation where basically you had pattern fly and PFE, and they were very similar, but different enough to be confusing. That's why in 2022, we released the second version of pattern fly elements, and our watchword for that version was one-to-one. We wanted the second version of PFE to be a one-to-one representation of the design principles of the pattern fly library, such that the end user wouldn't necessarily be able to tell that they were looking at a React app or an HTML page. So, yeah, the history of pattern fly elements. So the original PFE components were inspired by the pattern fly core, but they were different enough to be their own thing, and like we said, the technical needs were different, so it was kind of a different beast, but PFE 2.0 brought the best of pattern fly design to more use cases via spec standard HTML. So you could load up, you know, a PF card instead of importing card from pattern fly React, and you just drop it on your HTML page. Our goal was one-to-one representation. It's pattern fly design, but standardized for the web, not just for a particular web framework. So let's take a look at a few examples of pattern fly components. Here's an example of a pattern fly elements card. You see that we have this optional rounded boolean attribute where you can say is the card rounded or not. There are slots for the header content. Slot is a web component API, so the web component author can say, here's where the header goes, here's where the footer goes, and then the user can specify which slot a particular element goes into, and you can put multiple elements in the same slot. The paragraph here goes into the anonymous slot. It doesn't have a slot attribute, it's just the body slot of the card, and then we have here some buttons, some pattern fly buttons that slot into the footer, like you would have, you know, sort of a confirmation dialogue, and this is what that looks like. That's actually a real instance of pattern fly card loaded up in the browser, right there. Okay, we have our buttons here. They don't do anything, but same thing. Okay, we also have an accordion element, so that's a popular UI pattern where you'll have sort of like multiple disclosures that go in and close and hide and show content and whatnot. So here we have the four freedoms of the Free Software Foundation, and this is what it looks like when you load it up on the page. There's an optional single attribute you can put there so that it only shows one element at a time, so you can opt into that behavior or not. Make some weird problems with the mouse, but that's fine. We have a modal element, a modal dialogue, which will pop up some UI onto the screen, and this is a cool one because you can associate the modal. See, the trigger attribute points to the usage trigger ID, which is a button that lives somewhere else on the page, somewhere else in the DOM, and you as the developer don't have to write any JavaScript to hook those two things up together. You just have to say, this is the button that triggers the modal, here's the modal, and away we go. Let's see if I can overcome my input problems. Load up the modal, not so much. Oh, something happened. Well, you're going to have to take my word for it. This is why we don't live code children. You know what I can do? It looks like that. This is what it looks like when you open and close the modal. Great. Okay, so how do we make pattern fly elements? Now, in this section, the important thing for you to remember is that what I'm about to tell you about how we make the elements has no effect on how you use the elements. Our internal technical decisions don't limit you in terms of your options. So we build our elements using TypeScript, standard HTML, standard CSS, the Lit Web Components Framework, which is sort of the spiritual successor to the original Polymer project, and we use the pattern fly upstream design tokens. Okay? But just because we chose to use TypeScript and Lit, you don't have to. You can use the pattern fly elements in a React app, in a View app, in a WordPress site, whatever you want, in a Lit application if you want to. Here's sort of a typical example of what it might look like to author one of our components. So you can give it a tag name, PFTile, and you can extend from LitElement, which is our framework base class. If you squint, if you've ever written a React component or a View component or a Svelte component before, if you squint, you can see the outline of a typical JavaScript framework component. We have two reactive properties, selected, which is a Boolean, and stacked, which is an enum of strings, and you can say what the size is. Okay? This reflect option on the property means that setting the stacked property on the DOM object will reflect that state to the attribute on the HTML element, and that means now you can select with CSS for a tile that's stacked with large or small or whatever. Okay? And then here we have our HTML template where you can see we are reacting to the changes in the selected state and we are reacting to an internal class. Now, this looks like we're doing string concatenation, and so a lot of developers will sometimes say, oh, it's string concatenation, it's not performant, but don't make that mistake. This is a function which is called on this template which creates a template object in memory which has references to the exact places in the DOM and to all of the interpolations. So when I update the state of this element, it will only change the contents of this attribute. It doesn't have to re-render the entire DOM tree. There's no diffing, there's no V DOM, there's no memory overhead. It's just direct interaction with the DOM APIs but with a very nice developer experience. Again, although pattern fly elements are written using Lit, you don't have to use Lit, you can use them in any framework or in no framework. So how do you get pattern fly elements? If you're using NPM and the node ecosystem, you can just NPM install at pattern fly slash elements, use your bundlers, and away you go. You don't have to do that. I've spoken with teams who are building apps in Django or with Java or just writing HTML pages in Drupal. They don't have the time, the energy, the inclination, or the budget to mess with heavy, complicated JavaScript tooling. And really, who would want to? And I say that as a full-time JavaScript developer. So if you want to use these components, you can just drop in a link to a CDN, load up all the component definitions, and away you go. You can write some HTML, and you're off to the races. Of course, the browser will de-dupe all of these module references, so if you have isolated components in your CMS, you can just do this 100 times, and there's no performance penalty, basically. This pairs extremely well with a relatively new browser standard, which just landed in all three major engines this month called import maps. So if you want to do something like import from what's called a bare module specifier, instead of importing from a URL, I want this package, and I want this file in this package. And up in the head of your document, you can say that that specifier maps with your CDN, and you're good to go. Our goal for you is that you should be able to write more HTML and less JavaScript. You should reduce your tooling burden. You should practice standards-first development for knowledge transfer and future-proofing. And although frameworks are allowed, they aren't required. So that's where our components work. So I promised some performance. This is where you get your money value out of the presentation. So let's take a look. I did some comparisons. We're going to have problems with the mouse again, I think. One second. Okay, so here's the demo. It's just a card with some labels, a tooltip, and some switches which toggle the state on the card. I don't know if you can see that the corners can make a compact card. That's the demo. So I implemented this demo using web components and using pattern fly reacts with CR create react app. On the left we have pattern fly react. Just that demo, two and a half megabytes of JavaScript I had to download just to render the page. Just to render this text. Until you downloaded and ran those two and a half megabytes of JavaScript, you wouldn't know that we were talking about a react design system. No script, not allowed. The web components version, 222 kilobytes of JavaScript downloaded, and this all works with no script because all the content is in HTML. Both of these are unbundled, no optimizations over here, so if we wanted we could probably go in and optimize both, so it's kind of a quick and dirty comparison, but just to give you the idea. Looking at view source, create react app. The only content in this application is div id equals root. That's what the user sees when they load up the page. JavaScript is off or JavaScript is on and the script somehow didn't download or was corrupted along the way. Div id root. Over here, no script doesn't go for you. You still get all the text, search engines can read it, screen readers can read it. All your important content is still available. What about tooling burden? What about the developer experience? What about onboarding new developers, junior developers into your project? The package lock JSON for the react version of this application, you can't even read it on the screen, is 30,168 lines of code. To render a card and a switch and a tooltip. I wanted to print the list of packages instead of the package lock. It didn't fit in the terminal after I decreased the font size five times. How do we manage the packages in the HTML version? This import map which I generated by specifying which packages and files I wanted. What's that? 10 lines, 15 lines of JSON that you can just plot in your page. If I didn't want to do that, I could just load up the bundle from the CDN as well and one line of HTML that would do it. What's the future of pattern fly elements? First of all, we want to build more components. We haven't built out the full pattern fly library yet. Contributions are very much welcome and I invite you all to come and check out our issue tracker or just to go look at the list on patternfly.org and say, hey, we could use this one over there. We want to build react wrappers for these components. I said earlier that web components work with all the frameworks and that is true but unfortunately react, how can I put this delicately? Does not yet have full support for the HTML standard. In order to make it easier for react developers to use web components, what we can do is automatically generate these react wrappers that would turn a pfcard into a pfcard react object that would be easier to use from a react perspective. We are experimenting now with something called declarative shadow DOM. What this is is a new browser standard. It's supported today in Chrome and WebKit and it's gaining popularity in Mozilla so we hope they'll implement soon, go and vote on the Mozilla page. What declarative shadow DOM lets you do is on the server side calculate the state of your web component and stamp the shadow DOM onto the HTML page. Before declarative shadow DOM you had to run JavaScript in order to create that shadow root but now that we have declarative shadow DOM if I have an SSR situation I can just print the contents of my shadow root to the page in HTML and with JavaScript disabled everything will render the way we intended. It's incredible technology so we're working on different projects in order to get that on the go. Declarative shadow DOM also unlocks nicer APIs whereas if we had an imaginary pflink component that was supposed to wrap an anchor tag today we would want the developer to wrap a regular a tag in our pflink as sort of a decorator but with declarative shadow DOM that would let us do things just like expose the APIs directly on the element. Okay, how are we doing for time? Okay, so that brings us to a red hat design system so that was pattern fly elements that's sort of upstream pattern fly elements is like the fedora to our red hat design systems rel. Okay, so for those who have been around red hat for a long time they don't need me to ask the next question why do you have design systems because that'll make sense. It's great upstream downstream it's perfect but let's dive in a little bit more why do we have two design systems so pattern fly elements is upstream means it's open to the community it addresses community concerns not necessarily just only the concerns of the marketing department it's unbranded so you can put it in any app and it'll work as an unbranded experience and it's multi-purpose it's geared towards both web apps and towards pages and things like that with a particular emphasis on app development. Red hat design system is our downstream which means that it takes the core tools and concepts and shared code from pattern fly elements and implements a specific use case for them in particular use cases related to the marketing department and pages like redhat.com and product trials and customer portal and things like that. It's branded so it has all of the red hat brand standards built in right you don't have to like load up a special pattern fly red hat theme in order to make it look like red hat stuff like all the red hat design tokens are built in and it's primarily geared towards web pages as opposed to web apps although you can use our components for web apps as well there's nothing really stopping you. So a couple of case studies red hat product trials it's a multi-page app that's wrapped in a React SPA with micro front ends built in and it touches a lot of different areas because you know it has to talk to all these different products in red hat while also talking to the marketing side it's kind of a halfway house. So in red hat product trials a web component based micro front end system that web component part really was super critical for us because that's what let us build this out at scale right without having to burden the implementers of particular instances with our javascript tooling and our framework and keeping their package locks up to date and what not we could just tell them use this tag name load up the script and use this tag name and you're good to go so that was extremely helpful as well the shadow DOM gives us that encapsulation so different teams can work together on the same page without having to worry about stepping on each other's toes. Red hat product trials is linked from red hat com which uses the red hat design system it itself uses the red hat design system elements as well as pattern fly elements together and the react framework which manages the entire SPA can inject its react side state into the web components via javascript DOM properties or html attributes and that's how they can communicate with one another another case study that we've had is personalization so you land on a marketing page and you're like soon to be outlawed third party cookies tell the red hat marketing department a lot about who you are and what kind of things you're interested in so then the analytics scripts can come in and present personalized content to tell you know to tell you about something that you're most interested in well in order for those teams to do their job again we don't want to ever have to say the words to the people writing the analytics content npm install those are not words that I want to write in a in a direct message to anyone really you know low alley new so instead we can just tell them these are the tag names you know here are the design standards here's the docs pages with the guidelines and how to build them up and then they can go and build those personalized experiences inject them live onto the page without having to worry about complicated tool change of frameworks just html so that's our presentation I want to give a special thanks to all the pattern fly elements and red hat design system contributors which you can go and scroll and hover over at the slides afterwards especially to you all for help with the graphics thank you very much and we have a little bit of time for questions yeah so there's a lot of different ways it's basically up to you web components are the UI layer the component layer right so everything else is up to you so my preference is use the browser right there's just put a link that's works with screen readers works with everyone everyone knows what to expect there's a new browser API coming out now called view transitions which allows you to do more complicated things like animate between page transitions and what not and when that becomes widespread it's basically going to kill the single page application at least I hope it'll kill the single page application but let's say you're stuck with a classic framework or something like that so you can use your frameworks router and just render some web components in there if you're a little bit more keen a little bit more advanced and you build your web components you have to use lit your functional ones hooks a million different things we can talk about it afterwards so you can use that frameworks router or you can use a different frameworks router more declarative more imperative I prefer the PWA helpers router because it's very simple just gives you a call back location changed do this that's that's my favorite or questions do we have any questions from the chat yes yes yes yes I don't know right pattern fly elements is a downstream project from pattern fly core so the address for that question is the pattern fly core team I can tell you what I hope and what I dream but that's less helpful sure yeah how do they how do they build the presentation using web components well I wrote a plugin for 11t you download the plugin 11t is a static site generator so you can put front matter in your slides you write a deck with this 11t component you say you know here's the name of the thing whatever and then you just write your slides as markdown files in fact you know like two minutes before the presentation I was doing of course last minute last minute changes like you do so there are all the slides no more questions so sad so if you want to get involved find us on github github.com slash pattern fly slash pattern fly elements or if you want to do the red hat design system it's also open source we work out in the open all of our road maps are all available what not dive in give it a try you know we have a backlog there's issues that you can pick up there's some simple components there's some more complicated components I think we have five more minutes yeah okay yeah so it would it would work yeah how does mixing pattern fly react components with pattern fly elements components work okay so I'll give the answer in two parts there's how it works today and there's how we want it to work tomorrow how it works today is the same way that using any web component in react works like so if you want to use shoelace which is a popular open source web component library design system so you could just pop in like a SL button inside your react app because to put it delicately react has poor support for the html standards there are some annoying workarounds that you have to do with refs and attaching event listeners and setting properties and things like that if you want to do more complicated things if you use preact it's not a problem okay or what you could do and this is what we want to do in the future you can generate react components for the web components and what that does it takes a file called the custom elements manifest which is a json manifest of all of the apis on your custom element attribute slots, css properties, methods, events whatever it takes all that information and code generates a react component which can attach the event listeners and set the properties for you and all that and if you would do that and we hope to publish those soon then as far as the react user is concerned it looks like they're using a react component just under the hood they're using a more performant and standard html element so it sounded like it will generate react components will it be a react component or will it be you'll have so it's important to remember that react components are abstracted away from the DOM so what you'll have is a react component which represents the web component and then when react goes and prints its virtual DOM to the page it will print your web component there what the react component will do is it will abstract away react's poor support for the DOM other frameworks don't have this problem in Angular for example you can just attach an event listener to the web component in Svelte you can just set a property on the web component in Preact you can just do those things but react has very strong opinions about standards and what you should be allowed and not allowed to do with html so we have to implement workarounds for react so if we have like two more minutes there were some concerns about accessibility in web components and we're addressing that right now with a new standard called form associated custom elements if I still have the demo open here yeah here so if we inspect this switch component one can see great you'll notice that the switch is nested inside of a label same way that you would nest an input a native input inside of a label what a form associated custom element is it means that the browser when it submits that form it knows that this label is associated with my custom switch and I can set there's API to set the value on that switch so that when I submit the form over HTTP it'll read the value from my web component according to my code according to my web components code so I write a special color picker with an HTML label that's called form associated custom elements there's work being done right now on what's called cross root ARIA which means how do I associate a data list which lives in one shadow root with an input which lives in another shadow root over there so work is proceeding over there in the meantime there are various workarounds that we can do like sort of copying nodes from one place to another or moving ARIA attributes or something like that but the idea is that the web component user that the web component author will be the one in charge of implementing the accessibility we try our best on the design systems team to do that we have full time accessibility people thank you very much for attending the talk I hope it was interesting and I'm available for questions afterwards