fundamental-ngx
fundamental-ngx copied to clipboard
Skeleton Component
Is this a bug, enhancement, or feature request?
feature request
Briefly describe your proposal.
We would expect that Fundamentals supports something similar as MUI currently supports:
https://mui.com/components/skeleton/
Skeleton loading should be available for various elements, such as table, forms, headers, list, side navigation.
(dxp/ngx-dxp/issues/75)
The first goal:
- [x] research how this is done in other libraries
- [x] gather all needed information/design/assets
- [x] research and document the impact for NGX (maybe doing PoC)
- [x] breaking changes
- [x] present the summary after scrum
- [x] trying to break into tasks the implementation
Next Sprint Task - 1w
- [ ] skeleton impl in simple components (e.g. button, avatar)
- [ ] skeleton impl in complex components (e.g. table, form container)
- [ ] introduce a skeleton switch in doc examples
- [ ] present it to the designers for feedback
There exists two ways of providing this feature, let me describe pros & cons of both.
-
CSS Class. Something like here https://taiga-ui.dev/skeleton. It's a way simpler on the first glance because only applying of a css class is needed. Because of the reuse of existing HTML elements and putting this skeletons via pseudo elements they can inherit dimensions & border radius what is a very handy. The downsides are that in case of a complex components where not all the elements initially visible there is nothing to apply CSS classes to so we have to create an empty elements on our side by ourselves. Also, the biggest cons is that we should manage all the skeleton classes applying in our library, for the every single component (i mean add inputs not related to the component itself). I'm against this approach but I had to mention it here.
-
Separate Component. Something like here https://mui.com/material-ui/react-skeleton/ and in many other libraries. It doesn't look so easy in comparison with the first option because additional markup is needed. But as the benefits we have that we even shouldn't handle it in our library (i mean adding this skeleton to each component), except providing the skeleton component itself, all other stuff like creation the markup goes to the client side. I'm for that option.
Okay, after a call with @g-cheishvili he gave me idea that we can use both approaches together.
For some components we cannot use CSS Class approach because there is no html markup to apply those classes (exactly that i mentioned before). So we have to rely on the Separate Component approach like so, here it's also combined with the additional template so the fdSkeleton
directive can catch it and manage showing it by itself instead of using*ngIf
:
<fd-table [fdSkeleton]="loading">
<tr *ngFor="let row of tableRows | async">
<!-- Table cells are not visible before tableRows, cannot apply skeleton classes to the table cells -->
</tr>
<!-- Show loadingTemplate till tableRows aren't loaded -->
<ng-template #skeletonTemplate>
<tr>
<td><fd-skeleton></fd-skeleton></td>
<td><fd-skeleton></fd-skeleton></td>
<td><fd-skeleton></fd-skeleton></td>
</tr>
</ng-template>
</fd-table>
In the same time there are components the html markup of which is fully visible initially, so we could use CSS Class approach for them (it should be done with the directive but here is a bare class for better understanding).
<input fd-input [class.fd-skeleton]="loading" />
Also, in some complex components we have to manage these classes (directives) applying on the our (library) side - what's not good because we should to enhance many of the components.
Here is the solution - customers will be able to use skeletonTemplate
just now (it's easy to implement) to provide custom skeleton template and then we will iteratively enhance components so later these components be able to render their skeleton visual representation without the templates at all! For sure customers may opt out from using templates for those components but they may continue using it.
Hm, found some more cons of CSS Class approach (they're actual for taiga by the way)
- possible pseudo elements overlap, as if use class it's the only one possible way to create skeleton visual representation
- ~~event (host) listeners overlap, as angular hasn't defined priority of listeners.~~
Components which definitely need skeletons inside of them
Platform:
- ~~Approval Flow~~
- List
- Smart filter Bar
- Table
- ~~Thumbnail~~
- ~~Upload collection~~
- Value Help Dialog
- Form Generator
Core:
- Avatar
- Card (+ Charts)
- Carousel
- Table
- Timeline
- Provide bare Skeleton component to customers
More explanations https://arc.net/e/A4FA6542-73C4-4125-B5B7-C328AFF14567