[00:00.000 --> 00:08.320] Okay, so welcome everybody. [00:08.320 --> 00:14.400] So my name is Alexander and today we'll talk about user interface library and the problem [00:14.400 --> 00:17.320] of customization. [00:17.320 --> 00:24.120] So to give you some context, I'm a three-year-old React engineer and I'm working at MUI during [00:24.120 --> 00:30.600] the day and during the night I was working for OpenFoodFact which is a kind of Wikipedia [00:30.600 --> 00:37.120] for food products at the end, don't hesitate to ask for stickers for both. [00:37.120 --> 00:41.760] So for the few, we don't know what is the material, this is the homepage so that you [00:41.760 --> 00:46.520] can get what is the component we provide. [00:46.520 --> 00:51.760] And we have a usual problem of user interface library which is what the re-user want to [00:51.760 --> 00:53.160] do with it. [00:53.160 --> 01:00.520] So one aspect is making internal tools or a small MVP, you work in an NGO for example, [01:00.520 --> 01:02.880] this is one project I'm working on. [01:02.880 --> 01:06.720] I'm currently doing a lot of effort because you can see the colors are not the default [01:06.720 --> 01:11.720] one which is a lot better than most of the projects we're using. [01:11.720 --> 01:19.200] But you also have kind of real websites that do a bit more customization with the library [01:19.200 --> 01:23.840] but all the components are from MUI. [01:23.840 --> 01:29.440] So you get a conflict about what is interesting for you because for me working out of the [01:29.440 --> 01:30.440] box is super important. [01:30.440 --> 01:34.520] I don't want to spend more than five minutes to set up a button. [01:34.520 --> 01:39.160] If you're paying engineers, they can spend a bit of time on it. [01:39.160 --> 01:44.080] Being beginner-friendly is super important for me to get new contributors on the project [01:44.080 --> 01:49.600] for companies to don't spend time on onboarding and about customization. [01:49.600 --> 01:54.520] I think the example before was clear enough. [01:54.520 --> 02:01.920] So I will present you how I perceive customization across my learning journey. [02:01.920 --> 02:06.760] So I started into a consulting company and what you have to do most of the time is the [02:06.760 --> 02:16.080] designer comes to set up some specific colors and so you add a CSS specification, selectors. [02:16.080 --> 02:19.640] It has to be a bit more specific for some of them, you have a class name. [02:19.640 --> 02:25.760] You want to be again more specific, you add another class name and it works by magic. [02:25.760 --> 02:31.240] And one year later, you will know that in CSS, the more classes you put, the more likely [02:31.240 --> 02:36.920] you are to override the properties, which is called a CSS specificity for those who [02:36.920 --> 02:39.600] are not aware. [02:39.600 --> 02:42.240] For user interface library, this means only one thing. [02:42.240 --> 02:49.080] But all your style into one CSS class name so that your user will be able to override [02:49.080 --> 02:50.080] them. [02:50.080 --> 02:57.520] So here is one of the simplest components to override one class with a meaningful name [02:57.520 --> 03:00.560] and developers can override. [03:00.560 --> 03:02.120] That's not all for customization. [03:02.120 --> 03:07.640] Of course, you need to respect, to pass some attributes to your HTML, for example, to strictly [03:07.640 --> 03:10.120] speaking, disable your buttons. [03:10.120 --> 03:16.120] And you can allow a bit more with React, for example, spading custom props. [03:16.120 --> 03:17.480] So that's all for me. [03:17.480 --> 03:20.440] If you want to customize the style, it's CSS. [03:20.440 --> 03:24.000] And if you want to modify the behavior, you will use props. [03:24.000 --> 03:29.000] That's basically what you learn after a bit one year of development. [03:29.000 --> 03:33.200] And for me, it was the time to level up and to join the MUI. [03:33.200 --> 03:37.240] So I was thinking, yes, I will work on two of those tiny components. [03:37.240 --> 03:42.720] And the guys say, hmm, it will be slightly more complex. [03:42.720 --> 03:46.200] So you will work on two of the data grids. [03:46.200 --> 03:52.280] Was a bit scared about at least being able to use it, but fairly simple at the beginning. [03:52.280 --> 03:56.680] You define what is a row, the collection of objects, same for the columns. [03:56.680 --> 04:01.600] To pass everything and the components, magically do the stuff. [04:01.600 --> 04:05.520] But of course, such a component has a lot of features. [04:05.520 --> 04:11.480] And here is the problem of the complex components being able, at the same time, for you to manage [04:11.480 --> 04:14.920] them internally, but also to document them. [04:14.920 --> 04:20.640] Because if user was just taking your component, put it into their website, it would be nice. [04:20.640 --> 04:27.720] But of course, they want to modify how the filtering is working, how the cell are rendered. [04:27.720 --> 04:31.720] And sometimes they have very bad ideas to test. [04:31.720 --> 04:34.520] So here is one of the first issues I get. [04:34.520 --> 04:40.240] So it's complex because you can open a filter panel. [04:40.240 --> 04:44.400] Into this filter panel, you can select on which column you will do the selection. [04:44.400 --> 04:50.480] And they wanted to sort it by alphabetical order instead of the order of the columns. [04:50.480 --> 04:52.400] It makes a lot of sense. [04:52.400 --> 05:00.080] But the problem is, how do you allow the developers to access this really specific rendering without [05:00.080 --> 05:02.080] having to break everything? [05:02.080 --> 05:06.040] If you're following what you learned during your first year, you say, okay, it's a behavior [05:06.040 --> 05:09.000] modification, so I add the properties. [05:09.000 --> 05:15.120] And then you get a problem about how your documentation will look like in a bit one year. [05:15.120 --> 05:18.360] So you need to find a solution. [05:18.360 --> 05:24.960] So there is three main solutions, which we will talk about. [05:24.960 --> 05:28.840] So the first one is a headless, and basically it means you remove the problem. [05:28.840 --> 05:34.960] You say, I will not consider giving you the components, I give you only the logics. [05:34.960 --> 05:38.520] So you provide options here, for example, what are the columns, what are the data to [05:38.520 --> 05:46.800] render, and it returns you all the utility function to quickly set up a filtering rendering. [05:46.800 --> 05:51.680] So you're not any more responsible of rendering the select, so developers can do whatever [05:51.680 --> 05:53.440] they want in it. [05:53.440 --> 05:58.680] So it's super customizable because you do not deal with the components. [05:58.680 --> 06:03.520] It's clearly not out of the box because even the quick start example are more than hundreds [06:03.520 --> 06:05.520] of lines. [06:05.520 --> 06:11.560] And beginner-friendly, yes and no, because you strictly give them like legal pieces. [06:11.560 --> 06:17.800] They have a function, they know what to do, they can do whatever they want before, after, [06:17.800 --> 06:20.080] or with the results. [06:20.080 --> 06:23.920] But you're also responsible to pass all the attributes to the HTML elements, so you have [06:23.920 --> 06:25.320] to learn each of them. [06:25.320 --> 06:30.720] If you don't know, you need to pass, for example, a label ID to be a RIA compliant. [06:30.720 --> 06:38.720] There is no way to say you, eh, you forget this specification in the components. [06:38.720 --> 06:43.960] Another way to do is to provide the basic components, the case here of React admin, which like the [06:43.960 --> 06:50.560] name says, it's an administration panel. [06:50.560 --> 06:53.200] Basically this is how you define your administration panel. [06:53.200 --> 07:00.880] You get a provider that wraps all your application, and you define resources, which define how [07:00.880 --> 07:05.320] they will render the table. [07:05.320 --> 07:09.240] Most of the time, you don't want to get the default table because, like always, you want [07:09.240 --> 07:12.840] to do some customization, and so it's easy. [07:12.840 --> 07:18.480] You define your own list, so there is an example, and you can specify, okay, this colon ID will [07:18.480 --> 07:26.840] be text, the category is text also, published at, it will be a date, and so on. [07:26.840 --> 07:31.240] And if you're not happy about the default way to render a date, you just remove the [07:31.240 --> 07:37.240] date field, and you create your custom components with smaller components they provide, and [07:37.240 --> 07:42.360] you can go deeper and deeper as you want. [07:42.360 --> 07:47.280] The idea, in fact, is that they provide the basic components as small as possible, and [07:47.280 --> 07:52.960] the way to wrap them all together, which is the providers, and you get your application, [07:52.960 --> 07:58.120] and if you know this image, you know that the result can also be this one. [07:58.120 --> 08:02.720] This is, so you know Material UI, so you will recognize the code. [08:02.720 --> 08:11.040] It's a form control with an input and a select, and just below, it's a form control, a label, [08:11.040 --> 08:12.540] and a text field. [08:12.540 --> 08:17.520] It's a real code I wrote when I arrived, and it was not working. [08:17.520 --> 08:24.480] You can see the variant standard is not applied onto the text field, and you probably already [08:24.480 --> 08:29.240] guess why, it's because the text field is already a form control with a label, with [08:29.240 --> 08:36.240] an input, and an helper text, so without realizing, I was putting a form control into another [08:36.240 --> 08:39.640] one, so it did not work. [08:39.640 --> 08:43.160] The problem is not that it's not working, because it was my fault. [08:43.160 --> 08:48.400] The problem is that I was not able to get any warning into the console to say, me, hey, [08:48.400 --> 08:54.040] you're doing stupid stuff, but that's because people can take all the components they want [08:54.040 --> 09:01.080] and rub them in the order they want, and you cannot handle all the stupid adcage that developers [09:01.080 --> 09:06.640] could be able to do, so you cannot prevent them from doing a mistake. [09:06.640 --> 09:09.640] So here is a correction. [09:09.640 --> 09:15.800] If you want an example, this is Ikea page, fairly simple, but there is already six ways [09:15.800 --> 09:22.040] of not to do, and in two documentation, developers do not already read the section how to do, [09:22.040 --> 09:27.320] so how not to do, you are likely that they will never read it. [09:27.320 --> 09:32.480] So customization is nice, because you can already override your components. [09:32.480 --> 09:36.960] It works out of the box, if you stick with the default one, it's nice, but it's not [09:36.960 --> 09:44.400] beginner friendly, because you cannot prevent errors, and there is another fact, if you [09:44.400 --> 09:49.160] want to do customization, you need to understand how the providers are working, and it's super [09:49.160 --> 09:52.320] hard one to document, and two to explore. [09:52.320 --> 09:57.960] You cannot say, oh, I console log the props, and I saw all the attributes that are available, [09:57.960 --> 10:04.760] and I guess how they work, there is to use some provider and consumer. [10:04.760 --> 10:11.960] So now the last one, which are the slots used at MUI, so if you remember, the first example [10:11.960 --> 10:17.320] I give about customizing button is to add an end icon. [10:17.320 --> 10:22.680] We can apply the same thing for custom components, for example, I want to provide a custom filter [10:22.680 --> 10:28.000] panel, so I pass a props filter panel, but we arrive at the same problems, an infinite [10:28.000 --> 10:29.960] list of props. [10:29.960 --> 10:35.840] So we put some context, so we define the property slots, and we will document in a specific [10:35.840 --> 10:44.480] place, these are all the components you can override, and that works, but this is a kind [10:44.480 --> 10:50.560] of basic filter panel with a lot of subcomponents, a lot of logic and edge case that are already [10:50.560 --> 10:57.800] being solved, and you want to take advantage of all the issues we resolved. [10:57.800 --> 11:04.920] So the idea is to provide also slot props, so you say to my filter panel, which is kind [11:04.920 --> 11:10.520] of a box I can remove and replace by a custom one, I also want to put some inputs, so for [11:10.520 --> 11:16.880] example here I want to provide the property colon is sorted by ascending order, and the [11:16.880 --> 11:22.200] default component might support it, so of course if you replace it with a custom one [11:22.200 --> 11:28.400] and do not support these props it will not work, which is a complex case, but this is [11:28.400 --> 11:35.200] currently the solution to solve the initial issue sorting by ascending order. [11:35.200 --> 11:40.000] So it's customizable because in the worst case you remove the components and replace [11:40.000 --> 11:46.680] by a custom one, it works out of the box because if you don't want customization it's working, [11:46.680 --> 11:51.400] and begin off only because we have a single place for the interface between your code [11:51.400 --> 11:56.840] and our code which are the properties, so you remove the components and you know props [11:56.840 --> 12:03.760] pass to these components is the only responsibility we have to provide you, you don't have to [12:03.760 --> 12:11.000] expect props coming from somewhere else or modification of the wrapper because you see [12:11.000 --> 12:15.280] it has a new children. [12:15.280 --> 12:16.920] So which one is the best? [12:16.920 --> 12:21.160] I've already seen this question a lot of time on two Twitter and of course the answer [12:21.160 --> 12:26.000] is there is no best, it depends on how many time you are able to spend on your project [12:26.000 --> 12:34.160] and how much custom you want to be, and there is a last solution which is you can also not [12:34.160 --> 12:43.000] choose, it's an upcoming way to do it, so for example for a filter panel you can use [12:43.000 --> 12:49.400] slots to override it, so you have a way to say that your only props are your interface [12:49.400 --> 12:53.920] between the library and your custom components. [12:53.920 --> 12:59.560] You can use headless inside your custom components to say okay I know what I will get as a props [12:59.560 --> 13:06.960] so I can provide you a hook that will transform them into a helping functions, and if there [13:06.960 --> 13:13.000] is a lot of elements inside you can also provide the basic bricks to build your filter panel [13:13.000 --> 13:20.800] consuming the, for example your filter items props that are provided by the headless approach, [13:20.800 --> 13:27.960] so there is a way to say okay you can do whatever you want with a filter panel, if it's really [13:27.960 --> 13:32.480] common you will just have to pass props, it's more general if you want for example to modify [13:32.480 --> 13:37.000] the DOM, it's something like that when you have to mix everything, and if you want to [13:37.000 --> 13:45.400] do something completely different, you go to the trash and put your own components, [13:45.400 --> 13:58.720] and that's all for me. [13:58.720 --> 14:04.800] Thank you very much, we obviously have plenty of time for questions, so who wants to ask [14:04.800 --> 14:15.760] the first one? [14:15.760 --> 14:21.920] Hi first thank you very much for creating the data grid, it has saved my job countless [14:21.920 --> 14:32.560] times, my question was more related to, oh yeah I don't want to, okay, my question is [14:32.560 --> 14:40.240] related to another talk that we saw today called Penpot, which is an open source version [14:40.240 --> 14:50.960] of Figma basically, and MIUI has some design kits to use in different design tools, are [14:50.960 --> 14:57.760] you guys looking at Penpot, are you thinking about creating a design kit for it, I would [14:57.760 --> 14:59.920] love to use it, thank you. [14:59.920 --> 15:14.960] I have clearly no idea because it's a completely different team that is, okay, thank you. [15:14.960 --> 15:22.480] Hello, thank you for the presentation, a quick question regarding the design phase, did you [15:22.480 --> 15:27.080] consider about backward compatibility, about what? [15:27.080 --> 15:30.640] Backwards compatibility with previous versions of Material UI? [15:30.640 --> 15:36.000] Yes, but what is the relation with backwards compatibility? [15:36.000 --> 15:42.840] So with each new major version that Material UI has, usually there are quite a few breaking [15:42.840 --> 15:51.920] changes, so when you were talking about the considerations on the design phase about being [15:51.920 --> 15:59.000] beginner-friendly and all this stuff, was backwards compatibility a thought at that [15:59.000 --> 16:02.880] stage? [16:02.880 --> 16:13.440] I honestly don't understand how do you want to provide a backward compatibility for such [16:13.440 --> 16:16.400] a user library. [16:16.400 --> 16:26.800] I don't understand what you're expecting to get solved by the library. [16:26.800 --> 16:32.960] So you usually expect backwards compatibility so that every time that a major version is [16:32.960 --> 16:44.160] upgraded, your code does not break a lot, but that is not the case, unfortunately, usually. [16:44.160 --> 16:52.480] As long as you do not go from one major to another one, it's working. [16:52.480 --> 16:57.880] I mean, we follow the same verse, so if you're into V4, you can upgrade as long as you want [16:57.880 --> 16:59.960] and it will be working. [16:59.960 --> 17:01.680] Okay, thanks. [17:01.680 --> 17:17.160] Thank you, while I walk up, I see a little bit of trash here and there, so please, even [17:17.160 --> 17:22.080] if it's not yours, pick it up and put it in the bin. [17:22.080 --> 17:23.320] Thank you. [17:23.320 --> 17:27.120] So you showed us about slot props and slots. [17:27.120 --> 17:31.840] You said that it was basically the best trade-off between being beginner-friendly and customizable. [17:31.840 --> 17:36.800] I was wondering what if you have really complex components when the slot components also have [17:36.800 --> 17:38.800] slots themselves. [17:38.800 --> 17:41.680] Are you able to do this kind of cascade of slot props? [17:41.680 --> 17:46.760] There is this problem sometimes. [17:46.760 --> 17:53.600] It's problematic for documentation point of view because if you allow people to override [17:53.600 --> 18:02.200] the sub-slot, they will not implement all the edge case interfacing with the props provided [18:02.200 --> 18:08.760] and after that, they want to just pass the props to the wrapper components and, of course, [18:08.760 --> 18:15.840] it will break because they did not implement it the internal ones and it's problematic, [18:15.840 --> 18:23.400] but you are to say that the best way to mitigate is you do not provide a slot for every component [18:23.400 --> 18:28.520] just the stuff that can be considered as an independent. [18:28.520 --> 18:34.920] For example, a filter panel is super easy because you have an entire piece of software. [18:34.920 --> 18:37.160] It will get some filters in time. [18:37.160 --> 18:40.360] It needs to update its value and that's all. [18:40.360 --> 18:41.360] It's super clear. [18:41.360 --> 18:42.360] It's the same. [18:42.360 --> 18:44.360] You will not have sub-components. [18:44.360 --> 18:47.840] You want to customize except writing them by yourself. [18:47.840 --> 18:54.800] So it's really rare when you have a sub-component into another one for slots. [18:54.800 --> 18:55.800] Okay. [18:55.800 --> 18:58.280] And for the rest, you are using props, I suppose? [18:58.280 --> 18:59.280] Yes. [18:59.280 --> 19:05.800] And I think for now, we do not do it because we don't need to reach this level of simplifying [19:05.800 --> 19:12.840] customization, but I think providing the sub-components to do it is maybe the best way. [19:12.840 --> 19:18.240] For example, we have a toolbar and the way to overriding is you provide a slot to define [19:18.240 --> 19:23.600] what is the toolbar and we provide all the default buttons you wish to put into your [19:23.600 --> 19:24.600] toolbar. [19:24.600 --> 19:25.600] Okay. [19:25.600 --> 19:43.560] Thank you.