Okay, so welcome everybody.
So my name is Alexander and today we'll talk about user interface library and the problem
of customization.
So to give you some context, I'm a three-year-old React engineer and I'm working at MUI during
the day and during the night I was working for OpenFoodFact which is a kind of Wikipedia
for food products at the end, don't hesitate to ask for stickers for both.
So for the few, we don't know what is the material, this is the homepage so that you
can get what is the component we provide.
And we have a usual problem of user interface library which is what the re-user want to
do with it.
So one aspect is making internal tools or a small MVP, you work in an NGO for example,
this is one project I'm working on.
I'm currently doing a lot of effort because you can see the colors are not the default
one which is a lot better than most of the projects we're using.
But you also have kind of real websites that do a bit more customization with the library
but all the components are from MUI.
So you get a conflict about what is interesting for you because for me working out of the
box is super important.
I don't want to spend more than five minutes to set up a button.
If you're paying engineers, they can spend a bit of time on it.
Being beginner-friendly is super important for me to get new contributors on the project
for companies to don't spend time on onboarding and about customization.
I think the example before was clear enough.
So I will present you how I perceive customization across my learning journey.
So I started into a consulting company and what you have to do most of the time is the
designer comes to set up some specific colors and so you add a CSS specification, selectors.
It has to be a bit more specific for some of them, you have a class name.
You want to be again more specific, you add another class name and it works by magic.
And one year later, you will know that in CSS, the more classes you put, the more likely
you are to override the properties, which is called a CSS specificity for those who
are not aware.
For user interface library, this means only one thing.
But all your style into one CSS class name so that your user will be able to override
them.
So here is one of the simplest components to override one class with a meaningful name
and developers can override.
That's not all for customization.
Of course, you need to respect, to pass some attributes to your HTML, for example, to strictly
speaking, disable your buttons.
And you can allow a bit more with React, for example, spading custom props.
So that's all for me.
If you want to customize the style, it's CSS.
And if you want to modify the behavior, you will use props.
That's basically what you learn after a bit one year of development.
And for me, it was the time to level up and to join the MUI.
So I was thinking, yes, I will work on two of those tiny components.
And the guys say, hmm, it will be slightly more complex.
So you will work on two of the data grids.
Was a bit scared about at least being able to use it, but fairly simple at the beginning.
You define what is a row, the collection of objects, same for the columns.
To pass everything and the components, magically do the stuff.
But of course, such a component has a lot of features.
And here is the problem of the complex components being able, at the same time, for you to manage
them internally, but also to document them.
Because if user was just taking your component, put it into their website, it would be nice.
But of course, they want to modify how the filtering is working, how the cell are rendered.
And sometimes they have very bad ideas to test.
So here is one of the first issues I get.
So it's complex because you can open a filter panel.
Into this filter panel, you can select on which column you will do the selection.
And they wanted to sort it by alphabetical order instead of the order of the columns.
It makes a lot of sense.
But the problem is, how do you allow the developers to access this really specific rendering without
having to break everything?
If you're following what you learned during your first year, you say, okay, it's a behavior
modification, so I add the properties.
And then you get a problem about how your documentation will look like in a bit one year.
So you need to find a solution.
So there is three main solutions, which we will talk about.
So the first one is a headless, and basically it means you remove the problem.
You say, I will not consider giving you the components, I give you only the logics.
So you provide options here, for example, what are the columns, what are the data to
render, and it returns you all the utility function to quickly set up a filtering rendering.
So you're not any more responsible of rendering the select, so developers can do whatever
they want in it.
So it's super customizable because you do not deal with the components.
It's clearly not out of the box because even the quick start example are more than hundreds
of lines.
And beginner-friendly, yes and no, because you strictly give them like legal pieces.
They have a function, they know what to do, they can do whatever they want before, after,
or with the results.
But you're also responsible to pass all the attributes to the HTML elements, so you have
to learn each of them.
If you don't know, you need to pass, for example, a label ID to be a RIA compliant.
There is no way to say you, eh, you forget this specification in the components.
Another way to do is to provide the basic components, the case here of React admin, which like the
name says, it's an administration panel.
Basically this is how you define your administration panel.
You get a provider that wraps all your application, and you define resources, which define how
they will render the table.
Most of the time, you don't want to get the default table because, like always, you want
to do some customization, and so it's easy.
You define your own list, so there is an example, and you can specify, okay, this colon ID will
be text, the category is text also, published at, it will be a date, and so on.
And if you're not happy about the default way to render a date, you just remove the
date field, and you create your custom components with smaller components they provide, and
you can go deeper and deeper as you want.
The idea, in fact, is that they provide the basic components as small as possible, and
the way to wrap them all together, which is the providers, and you get your application,
and if you know this image, you know that the result can also be this one.
This is, so you know Material UI, so you will recognize the code.
It's a form control with an input and a select, and just below, it's a form control, a label,
and a text field.
It's a real code I wrote when I arrived, and it was not working.
You can see the variant standard is not applied onto the text field, and you probably already
guess why, it's because the text field is already a form control with a label, with
an input, and an helper text, so without realizing, I was putting a form control into another
one, so it did not work.
The problem is not that it's not working, because it was my fault.
The problem is that I was not able to get any warning into the console to say, me, hey,
you're doing stupid stuff, but that's because people can take all the components they want
and rub them in the order they want, and you cannot handle all the stupid adcage that developers
could be able to do, so you cannot prevent them from doing a mistake.
So here is a correction.
If you want an example, this is Ikea page, fairly simple, but there is already six ways
of not to do, and in two documentation, developers do not already read the section how to do,
so how not to do, you are likely that they will never read it.
So customization is nice, because you can already override your components.
It works out of the box, if you stick with the default one, it's nice, but it's not
beginner friendly, because you cannot prevent errors, and there is another fact, if you
want to do customization, you need to understand how the providers are working, and it's super
hard one to document, and two to explore.
You cannot say, oh, I console log the props, and I saw all the attributes that are available,
and I guess how they work, there is to use some provider and consumer.
So now the last one, which are the slots used at MUI, so if you remember, the first example
I give about customizing button is to add an end icon.
We can apply the same thing for custom components, for example, I want to provide a custom filter
panel, so I pass a props filter panel, but we arrive at the same problems, an infinite
list of props.
So we put some context, so we define the property slots, and we will document in a specific
place, these are all the components you can override, and that works, but this is a kind
of basic filter panel with a lot of subcomponents, a lot of logic and edge case that are already
being solved, and you want to take advantage of all the issues we resolved.
So the idea is to provide also slot props, so you say to my filter panel, which is kind
of a box I can remove and replace by a custom one, I also want to put some inputs, so for
example here I want to provide the property colon is sorted by ascending order, and the
default component might support it, so of course if you replace it with a custom one
and do not support these props it will not work, which is a complex case, but this is
currently the solution to solve the initial issue sorting by ascending order.
So it's customizable because in the worst case you remove the components and replace
by a custom one, it works out of the box because if you don't want customization it's working,
and begin off only because we have a single place for the interface between your code
and our code which are the properties, so you remove the components and you know props
pass to these components is the only responsibility we have to provide you, you don't have to
expect props coming from somewhere else or modification of the wrapper because you see
it has a new children.
So which one is the best?
I've already seen this question a lot of time on two Twitter and of course the answer
is there is no best, it depends on how many time you are able to spend on your project
and how much custom you want to be, and there is a last solution which is you can also not
choose, it's an upcoming way to do it, so for example for a filter panel you can use
slots to override it, so you have a way to say that your only props are your interface
between the library and your custom components.
You can use headless inside your custom components to say okay I know what I will get as a props
so I can provide you a hook that will transform them into a helping functions, and if there
is a lot of elements inside you can also provide the basic bricks to build your filter panel
consuming the, for example your filter items props that are provided by the headless approach,
so there is a way to say okay you can do whatever you want with a filter panel, if it's really
common you will just have to pass props, it's more general if you want for example to modify
the DOM, it's something like that when you have to mix everything, and if you want to
do something completely different, you go to the trash and put your own components,
and that's all for me.
Thank you very much, we obviously have plenty of time for questions, so who wants to ask
the first one?
Hi first thank you very much for creating the data grid, it has saved my job countless
times, my question was more related to, oh yeah I don't want to, okay, my question is
related to another talk that we saw today called Penpot, which is an open source version
of Figma basically, and MIUI has some design kits to use in different design tools, are
you guys looking at Penpot, are you thinking about creating a design kit for it, I would
love to use it, thank you.
I have clearly no idea because it's a completely different team that is, okay, thank you.
Hello, thank you for the presentation, a quick question regarding the design phase, did you
consider about backward compatibility, about what?
Backwards compatibility with previous versions of Material UI?
Yes, but what is the relation with backwards compatibility?
So with each new major version that Material UI has, usually there are quite a few breaking
changes, so when you were talking about the considerations on the design phase about being
beginner-friendly and all this stuff, was backwards compatibility a thought at that
stage?
I honestly don't understand how do you want to provide a backward compatibility for such
a user library.
I don't understand what you're expecting to get solved by the library.
So you usually expect backwards compatibility so that every time that a major version is
upgraded, your code does not break a lot, but that is not the case, unfortunately, usually.
As long as you do not go from one major to another one, it's working.
I mean, we follow the same verse, so if you're into V4, you can upgrade as long as you want
and it will be working.
Okay, thanks.
Thank you, while I walk up, I see a little bit of trash here and there, so please, even
if it's not yours, pick it up and put it in the bin.
Thank you.
So you showed us about slot props and slots.
You said that it was basically the best trade-off between being beginner-friendly and customizable.
I was wondering what if you have really complex components when the slot components also have
slots themselves.
Are you able to do this kind of cascade of slot props?
There is this problem sometimes.
It's problematic for documentation point of view because if you allow people to override
the sub-slot, they will not implement all the edge case interfacing with the props provided
and after that, they want to just pass the props to the wrapper components and, of course,
it will break because they did not implement it the internal ones and it's problematic,
but you are to say that the best way to mitigate is you do not provide a slot for every component
just the stuff that can be considered as an independent.
For example, a filter panel is super easy because you have an entire piece of software.
It will get some filters in time.
It needs to update its value and that's all.
It's super clear.
It's the same.
You will not have sub-components.
You want to customize except writing them by yourself.
So it's really rare when you have a sub-component into another one for slots.
Okay.
And for the rest, you are using props, I suppose?
Yes.
And I think for now, we do not do it because we don't need to reach this level of simplifying
customization, but I think providing the sub-components to do it is maybe the best way.
For example, we have a toolbar and the way to overriding is you provide a slot to define
what is the toolbar and we provide all the default buttons you wish to put into your
toolbar.
Okay.
Thank you.