@gitlab/ui 66.7.1 → 66.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/tokens/css/tokens.css +1 -1
- package/dist/tokens/css/tokens.dark.css +1 -1
- package/dist/tokens/js/tokens.dark.js +1 -1
- package/dist/tokens/js/tokens.js +1 -1
- package/dist/tokens/scss/_tokens.dark.scss +1 -1
- package/dist/tokens/scss/_tokens.scss +1 -1
- package/dist/utility_classes.css +1 -1
- package/dist/utility_classes.css.map +1 -1
- package/package.json +1 -1
- package/src/components/base/skeleton_loader/skeleton_loader.md +23 -0
- package/src/scss/utilities.scss +83 -0
- package/src/scss/utility-mixins/animation.scss +77 -0
- package/src/scss/utility-mixins/sizing.scss +14 -0
package/package.json
CHANGED
|
@@ -9,6 +9,29 @@ loading animation. Any skeleton state components should be created with
|
|
|
9
9
|
`<gl-skeleton-loader></gl-skeleton-loader>`. If no shape is passed via the slot the default skeleton
|
|
10
10
|
will be used. See "Default" and "Default With Custom Props" examples.
|
|
11
11
|
|
|
12
|
+
**NOTE:** Skeleton loaders can also be composed with a `.gl-animate-skeleton-loader`
|
|
13
|
+
CSS class. This CSS-based approach is easier to make responsive and match mocked elements.
|
|
14
|
+
Feel free to use this approach if it suits your use case and please leave your
|
|
15
|
+
feedback in this [Feedback for css-based skeleton loading
|
|
16
|
+
indicator](https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2319) issue.
|
|
17
|
+
To improve developer experience and simplify matching Pajamas styles we're considering
|
|
18
|
+
several improvements in the future, including adding more CSS util classes for
|
|
19
|
+
this animation, or creating a dedicated component. Here is an example of how
|
|
20
|
+
you could replicate the default `<gl-skeleton-loader />` behavior with the
|
|
21
|
+
CSS-based approach:
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<div>
|
|
25
|
+
<div class="gl-animate-skeleton-loader gl-h-4 gl-rounded-base gl-my-3 gl-max-w-20!"></div>
|
|
26
|
+
<div class="gl-animate-skeleton-loader gl-h-4 gl-rounded-base gl-my-3 gl-max-w-30!"></div>
|
|
27
|
+
<div class="gl-animate-skeleton-loader gl-h-4 gl-rounded-base gl-my-3 gl-max-w-26!"></div>
|
|
28
|
+
</div>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
See
|
|
32
|
+
[animation.scss](https://gitlab.com/gitlab-org/gitlab-ui/-/blob/main/src/scss/utility-mixins/animation.scss#L17)
|
|
33
|
+
to learn more.
|
|
34
|
+
|
|
12
35
|
## Progressive Loading
|
|
13
36
|
|
|
14
37
|
Determine if progressive loading is available, if it is break apart the skeleton to load data as it
|
package/src/scss/utilities.scss
CHANGED
|
@@ -60,6 +60,19 @@
|
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
$gl-animate-skeleton-loader-max-width: 64 * $grid-size;
|
|
64
|
+
|
|
65
|
+
@keyframes gl-keyframes-skeleton-loader {
|
|
66
|
+
|
|
67
|
+
0% {
|
|
68
|
+
background-position-x: -$gl-animate-skeleton-loader-max-width;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
100% {
|
|
72
|
+
background-position-x: $gl-animate-skeleton-loader-max-width;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
63
76
|
.gl-spin {
|
|
64
77
|
animation: gl-spinner-rotate 2s infinite linear;
|
|
65
78
|
}
|
|
@@ -67,6 +80,48 @@
|
|
|
67
80
|
.gl-spin\! {
|
|
68
81
|
animation: gl-spinner-rotate 2s infinite linear !important;
|
|
69
82
|
}
|
|
83
|
+
|
|
84
|
+
.gl-animate-skeleton-loader {
|
|
85
|
+
$max-width: $gl-animate-skeleton-loader-max-width;
|
|
86
|
+
|
|
87
|
+
overflow: hidden;
|
|
88
|
+
max-width: $max-width;
|
|
89
|
+
background-size: $max-width 100%;
|
|
90
|
+
background-position: -$max-width 0;
|
|
91
|
+
background-color: $gray-100;
|
|
92
|
+
background-image: linear-gradient(to right,
|
|
93
|
+
$gray-100 0,
|
|
94
|
+
$gray-50 23%,
|
|
95
|
+
$gray-50 27%,
|
|
96
|
+
$gray-100 50%);
|
|
97
|
+
background-repeat: no-repeat;
|
|
98
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
99
|
+
animation: gl-keyframes-skeleton-loader 2.5s linear;
|
|
100
|
+
animation-delay: inherit;
|
|
101
|
+
animation-iteration-count: 3;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.gl-animate-skeleton-loader\! {
|
|
106
|
+
$max-width: $gl-animate-skeleton-loader-max-width !important;
|
|
107
|
+
|
|
108
|
+
overflow: hidden !important;
|
|
109
|
+
max-width: $max-width !important;
|
|
110
|
+
background-size: $max-width 100% !important;
|
|
111
|
+
background-position: -$max-width 0 !important;
|
|
112
|
+
background-color: $gray-100 !important;
|
|
113
|
+
background-image: linear-gradient(to right,
|
|
114
|
+
$gray-100 0,
|
|
115
|
+
$gray-50 23%,
|
|
116
|
+
$gray-50 27%,
|
|
117
|
+
$gray-100 50%) !important;
|
|
118
|
+
background-repeat: no-repeat !important;
|
|
119
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
120
|
+
animation: gl-keyframes-skeleton-loader 2.5s linear !important;
|
|
121
|
+
animation-delay: inherit !important;
|
|
122
|
+
animation-iteration-count: 3 !important;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
70
125
|
.gl-appearance-none {
|
|
71
126
|
appearance: none;
|
|
72
127
|
-moz-appearance: none;
|
|
@@ -5396,6 +5451,14 @@
|
|
|
5396
5451
|
max-width: $gl-spacing-scale-15 !important;
|
|
5397
5452
|
}
|
|
5398
5453
|
|
|
5454
|
+
.gl-max-w-20 {
|
|
5455
|
+
max-width: $gl-spacing-scale-20;
|
|
5456
|
+
}
|
|
5457
|
+
|
|
5458
|
+
.gl-max-w-20\! {
|
|
5459
|
+
max-width: $gl-spacing-scale-20 !important;
|
|
5460
|
+
}
|
|
5461
|
+
|
|
5399
5462
|
.gl-max-w-26 {
|
|
5400
5463
|
max-width: $gl-spacing-scale-26;
|
|
5401
5464
|
}
|
|
@@ -5404,6 +5467,14 @@
|
|
|
5404
5467
|
max-width: $gl-spacing-scale-26 !important;
|
|
5405
5468
|
}
|
|
5406
5469
|
|
|
5470
|
+
.gl-max-w-30 {
|
|
5471
|
+
max-width: $gl-spacing-scale-30;
|
|
5472
|
+
}
|
|
5473
|
+
|
|
5474
|
+
.gl-max-w-30\! {
|
|
5475
|
+
max-width: $gl-spacing-scale-30 !important;
|
|
5476
|
+
}
|
|
5477
|
+
|
|
5407
5478
|
.gl-max-w-34 {
|
|
5408
5479
|
max-width: $gl-spacing-scale-34;
|
|
5409
5480
|
}
|
|
@@ -5579,6 +5650,18 @@
|
|
|
5579
5650
|
max-width: 80% !important;
|
|
5580
5651
|
}
|
|
5581
5652
|
}
|
|
5653
|
+
|
|
5654
|
+
.gl-lg-max-w-50p {
|
|
5655
|
+
@include gl-media-breakpoint-up(lg) {
|
|
5656
|
+
max-width: 50%;
|
|
5657
|
+
}
|
|
5658
|
+
}
|
|
5659
|
+
|
|
5660
|
+
.gl-lg-max-w-50p\! {
|
|
5661
|
+
@include gl-media-breakpoint-up(lg) {
|
|
5662
|
+
max-width: 50% !important;
|
|
5663
|
+
}
|
|
5664
|
+
}
|
|
5582
5665
|
.gl-p-0 {
|
|
5583
5666
|
padding: 0;
|
|
5584
5667
|
}
|
|
@@ -11,3 +11,80 @@
|
|
|
11
11
|
@mixin gl-spin {
|
|
12
12
|
animation: gl-spinner-rotate 2s infinite linear;
|
|
13
13
|
}
|
|
14
|
+
|
|
15
|
+
$gl-animate-skeleton-loader-max-width: 64 * $grid-size;
|
|
16
|
+
// Adds a sliding shining wave to element's background to indicate loading
|
|
17
|
+
//
|
|
18
|
+
// USAGE NOTES: if you're using `gl-max-w-xx` you'll need to add
|
|
19
|
+
// important (e.g. `gl-max-w-20!`). This is because `.gl-animate-skeleton-loader` already
|
|
20
|
+
// has a `max-width` statement, and we need to override it. You can override it
|
|
21
|
+
// only with lower numbers. Width rules (`gl-w-xx`) don't need an override, you
|
|
22
|
+
// can use them as-is. If you want to "synchronize" two elements next to each
|
|
23
|
+
// other, try adding `animation-delay` to offset elements.
|
|
24
|
+
//
|
|
25
|
+
// Simple example:
|
|
26
|
+
// ```html
|
|
27
|
+
// <div>
|
|
28
|
+
// <div class="gl-animate-skeleton-loader gl-h-4 gl-rounded-base gl-my-3"></div>
|
|
29
|
+
// <div class="gl-animate-skeleton-loader gl-h-4 gl-rounded-base gl-my-3"></div>
|
|
30
|
+
// <div class="gl-animate-skeleton-loader gl-h-4 gl-rounded-base gl-my-3"></div>
|
|
31
|
+
// </div>
|
|
32
|
+
// ```
|
|
33
|
+
//
|
|
34
|
+
// More complex example:
|
|
35
|
+
// (with different shapes and an animation delay for offset elements):
|
|
36
|
+
// ```html
|
|
37
|
+
// <div class="gl-display-flex gl-flex-direction-column gl-gap-2 gl-w-30">
|
|
38
|
+
// <div class="gl-animate-skeleton-loader gl-h-8 gl-rounded-base gl-mb-4"></div>
|
|
39
|
+
// <div class="gl-display-flex gl-flex-direction-row gl-gap-2">
|
|
40
|
+
// <div class="gl-animate-skeleton-loader gl-h-8 gl-w-8 gl-rounded-full"></div>
|
|
41
|
+
// <div class="gl-flex-grow-1" style="animation-delay: 100ms">
|
|
42
|
+
// <div class="gl-animate-skeleton-loader gl-h-4 gl-rounded-base gl-my-2"></div>
|
|
43
|
+
// <div class="gl-animate-skeleton-loader gl-h-4 gl-rounded-base gl-my-2"></div>
|
|
44
|
+
// <div class="gl-animate-skeleton-loader gl-display-inline-block gl-h-4 gl-w-10 gl-rounded-base gl-my-2"></div>
|
|
45
|
+
// <div class="gl-animate-skeleton-loader gl-display-inline-block gl-h-4 gl-w-10 gl-rounded-base gl-my-2" style="animation-delay: 250ms"></div>
|
|
46
|
+
// </div>
|
|
47
|
+
// </div>
|
|
48
|
+
// </div>
|
|
49
|
+
// ```
|
|
50
|
+
@mixin gl-animate-skeleton-loader {
|
|
51
|
+
$max-width: $gl-animate-skeleton-loader-max-width;
|
|
52
|
+
|
|
53
|
+
overflow: hidden;
|
|
54
|
+
max-width: $max-width;
|
|
55
|
+
background-size: $max-width 100%;
|
|
56
|
+
background-position: -$max-width 0;
|
|
57
|
+
background-color: $gray-100;
|
|
58
|
+
background-image: linear-gradient(to right,
|
|
59
|
+
$gray-100 0,
|
|
60
|
+
$gray-50 23%,
|
|
61
|
+
$gray-50 27%,
|
|
62
|
+
$gray-100 50%);
|
|
63
|
+
background-repeat: no-repeat;
|
|
64
|
+
|
|
65
|
+
// Enable animation only for users who don't have a preference
|
|
66
|
+
// for reduced animation
|
|
67
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
68
|
+
animation: gl-keyframes-skeleton-loader 2.5s linear;
|
|
69
|
+
animation-delay: inherit;
|
|
70
|
+
animation-iteration-count: 3;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@keyframes gl-keyframes-skeleton-loader {
|
|
75
|
+
// Skeleton loader animation basically moves background from `x=-100%` to
|
|
76
|
+
// `x=+100%`, so that at the beginning and at the end of the animation loop no
|
|
77
|
+
// gradient is leaking to the visible part. But we can't use percent-based
|
|
78
|
+
// positioning, for animation speed would be different for elements with
|
|
79
|
+
// different width. So we use a predefined max-width for
|
|
80
|
+
// `.gl-animate-skeleton-loader`, and use its value for `-100%` and `+100%`
|
|
81
|
+
// positioning.
|
|
82
|
+
|
|
83
|
+
0% {
|
|
84
|
+
background-position-x: -$gl-animate-skeleton-loader-max-width;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
100% {
|
|
88
|
+
background-position-x: $gl-animate-skeleton-loader-max-width;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -428,10 +428,18 @@
|
|
|
428
428
|
max-width: $gl-spacing-scale-15;
|
|
429
429
|
}
|
|
430
430
|
|
|
431
|
+
@mixin gl-max-w-20 {
|
|
432
|
+
max-width: $gl-spacing-scale-20;
|
|
433
|
+
}
|
|
434
|
+
|
|
431
435
|
@mixin gl-max-w-26 {
|
|
432
436
|
max-width: $gl-spacing-scale-26;
|
|
433
437
|
}
|
|
434
438
|
|
|
439
|
+
@mixin gl-max-w-30 {
|
|
440
|
+
max-width: $gl-spacing-scale-30;
|
|
441
|
+
}
|
|
442
|
+
|
|
435
443
|
@mixin gl-max-w-34 {
|
|
436
444
|
max-width: $gl-spacing-scale-34;
|
|
437
445
|
}
|
|
@@ -527,3 +535,9 @@
|
|
|
527
535
|
max-width: 80%;
|
|
528
536
|
}
|
|
529
537
|
}
|
|
538
|
+
|
|
539
|
+
@mixin gl-lg-max-w-50p {
|
|
540
|
+
@include gl-media-breakpoint-up(lg) {
|
|
541
|
+
max-width: 50%;
|
|
542
|
+
}
|
|
543
|
+
}
|