@threadlabs/looma 0.39.0 → 0.39.1
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/components/ui-skeleton/ui-skeleton.html +36 -7
- package/components/ui-skeleton/ui-skeleton.js +46 -0
- package/dist/index.js +13 -12
- package/docs/catalog.json +9 -9
- package/package.json +1 -1
- package/styles/ui-skeleton.css +30 -5
- package/vanilla/UiSkeleton.js +5 -3
- package/vue/UiSkeleton.vue +71 -10
- package/vue/chunks/UiSkeleton.js +41 -9
- package/vue/components.css +30 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<template component="ui-skeleton">
|
|
1
|
+
<template component="ui-skeleton" module="./ui-skeleton.js">
|
|
2
2
|
<defs>
|
|
3
3
|
<prop name="shape" type="keyword" values="text, circle, rectangle" default="text"
|
|
4
4
|
>The content's silhouette. text reserves one inherited line box with a shorter bar inside it; circle matches a medium Avatar; rectangle reserves a media
|
|
@@ -8,8 +8,12 @@
|
|
|
8
8
|
Avatar's outer size for circles.</prop>
|
|
9
9
|
<prop name="height" type="string" default=""
|
|
10
10
|
>Block size as a CSS length. Empty reserves one line for text, a square for circles, or 8rem for rectangles. Set only width to keep a circle square.</prop>
|
|
11
|
-
<prop
|
|
12
|
-
|
|
11
|
+
<prop
|
|
12
|
+
name="animated"
|
|
13
|
+
type="boolean"
|
|
14
|
+
default="true"
|
|
15
|
+
default-true-reason="A travelling highlight identifies pending content by default; reduced-motion preferences always keep it static."
|
|
16
|
+
>Moves a subtle highlight from left to right. On by default; pass false to keep it static. Reduced-motion preferences always disable the shimmer.</prop>
|
|
13
17
|
</defs>
|
|
14
18
|
<span aria-hidden="true" style:--ui-skeleton-width="$width" style:--ui-skeleton-height="$height"></span>
|
|
15
19
|
<style>
|
|
@@ -22,8 +26,20 @@
|
|
|
22
26
|
syntax: "*";
|
|
23
27
|
inherits: false;
|
|
24
28
|
}
|
|
29
|
+
@property --_ui-skeleton-viewport-x {
|
|
30
|
+
syntax: "<length>";
|
|
31
|
+
inherits: false;
|
|
32
|
+
initial-value: 0px;
|
|
33
|
+
}
|
|
34
|
+
@property --_ui-skeleton-viewport-scale {
|
|
35
|
+
syntax: "<number>";
|
|
36
|
+
inherits: false;
|
|
37
|
+
initial-value: 1;
|
|
38
|
+
}
|
|
25
39
|
|
|
26
40
|
:host {
|
|
41
|
+
--_ui-skeleton-paint-x: var(--_ui-skeleton-viewport-x);
|
|
42
|
+
--_ui-skeleton-paint-scale: var(--_ui-skeleton-viewport-scale);
|
|
27
43
|
display: block !important;
|
|
28
44
|
position: relative;
|
|
29
45
|
box-sizing: border-box !important;
|
|
@@ -65,23 +81,36 @@
|
|
|
65
81
|
}
|
|
66
82
|
|
|
67
83
|
:host([animated])::before {
|
|
68
|
-
|
|
84
|
+
background-image: linear-gradient(
|
|
85
|
+
90deg,
|
|
86
|
+
transparent,
|
|
87
|
+
light-dark(rgb(255 255 255 / 0.6), rgb(255 255 255 / 0.14)) 50%,
|
|
88
|
+
transparent
|
|
89
|
+
);
|
|
90
|
+
background-size: calc(100vw / var(--_ui-skeleton-paint-scale)) 100%;
|
|
91
|
+
background-position: calc(0vw - var(--_ui-skeleton-paint-x)) 0;
|
|
92
|
+
background-repeat: repeat-x;
|
|
93
|
+
animation: ui-skeleton-shimmer 3s linear infinite;
|
|
69
94
|
}
|
|
70
|
-
@keyframes ui-skeleton-
|
|
71
|
-
|
|
72
|
-
|
|
95
|
+
@keyframes ui-skeleton-shimmer {
|
|
96
|
+
to {
|
|
97
|
+
background-position: calc(100vw / var(--_ui-skeleton-paint-scale) - var(--_ui-skeleton-paint-x)) 0;
|
|
73
98
|
}
|
|
74
99
|
}
|
|
75
100
|
@media (prefers-reduced-motion: reduce) {
|
|
76
101
|
:host([animated])::before {
|
|
77
102
|
animation: none;
|
|
103
|
+
background-image: none;
|
|
78
104
|
}
|
|
79
105
|
}
|
|
80
106
|
@media (forced-colors: active) {
|
|
81
107
|
:host::before {
|
|
82
108
|
background: CanvasText;
|
|
83
109
|
opacity: 0.2;
|
|
110
|
+
}
|
|
111
|
+
:host([animated])::before {
|
|
84
112
|
animation: none;
|
|
113
|
+
background-image: none;
|
|
85
114
|
}
|
|
86
115
|
}
|
|
87
116
|
:host[hidden] {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keep one viewport gradient aligned through mounting, scrolling and transformed surfaces.
|
|
3
|
+
* @lifecycle CSS owns motion preferences; geometry tracking stops with the animation or disconnect.
|
|
4
|
+
*/
|
|
5
|
+
export function connect(host) {
|
|
6
|
+
const element = host.element;
|
|
7
|
+
const view = element.ownerDocument.defaultView;
|
|
8
|
+
let motion;
|
|
9
|
+
let frame = 0;
|
|
10
|
+
let previousPosition = "";
|
|
11
|
+
let previousScale = "";
|
|
12
|
+
const trackPosition = () => {
|
|
13
|
+
frame = 0;
|
|
14
|
+
if (motion?.playState !== "running") return;
|
|
15
|
+
const bounds = element.getBoundingClientRect();
|
|
16
|
+
const width = parseFloat(view.getComputedStyle(element).width);
|
|
17
|
+
const scale = bounds.width > 0 && width > 0 ? bounds.width / width : 1;
|
|
18
|
+
const position = `${bounds.left / scale}px`;
|
|
19
|
+
const scaleValue = String(scale);
|
|
20
|
+
if (position !== previousPosition) {
|
|
21
|
+
element.style.setProperty("--_ui-skeleton-viewport-x", position);
|
|
22
|
+
previousPosition = position;
|
|
23
|
+
}
|
|
24
|
+
if (scaleValue !== previousScale) {
|
|
25
|
+
element.style.setProperty("--_ui-skeleton-viewport-scale", scaleValue);
|
|
26
|
+
previousScale = scaleValue;
|
|
27
|
+
}
|
|
28
|
+
frame = view.requestAnimationFrame(trackPosition);
|
|
29
|
+
};
|
|
30
|
+
const synchronize = () => {
|
|
31
|
+
const names = view.getComputedStyle(element, "::before").animationName.split(",").map(name => name.trim());
|
|
32
|
+
for (const animation of element.getAnimations({ subtree: true })) {
|
|
33
|
+
if (names.includes(animation.animationName)) {
|
|
34
|
+
motion = animation;
|
|
35
|
+
motion.startTime = 0;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (!frame) trackPosition();
|
|
39
|
+
};
|
|
40
|
+
element.addEventListener("animationstart", synchronize);
|
|
41
|
+
synchronize();
|
|
42
|
+
return () => {
|
|
43
|
+
element.removeEventListener("animationstart", synchronize);
|
|
44
|
+
view.cancelAnimationFrame(frame);
|
|
45
|
+
};
|
|
46
|
+
}
|