@byline/ui 2.6.0 → 2.7.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/dist/components/shimmer/shimmer.d.ts +13 -1
- package/dist/components/shimmer/shimmer.js +29 -20
- package/dist/components/shimmer/shimmer_module.css +4 -4
- package/dist/styles/styles.css +3 -0
- package/package.json +2 -2
- package/src/components/shimmer/shimmer.module.css +8 -4
- package/src/components/shimmer/shimmer.tsx +34 -9
- package/src/styles/functional/surfaces.css +13 -1
|
@@ -2,11 +2,23 @@ import type React from 'react';
|
|
|
2
2
|
interface ShimmerProps {
|
|
3
3
|
className?: string;
|
|
4
4
|
width?: string | number;
|
|
5
|
+
/**
|
|
6
|
+
* Height of the bar. For the single-bar variants (`rectangular`,
|
|
7
|
+
* `circular`, and single-line `text`) this sizes the bar itself. For the
|
|
8
|
+
* multi-line text variant (`variant="text"` with `lines > 1`) it sizes the
|
|
9
|
+
* container that holds the lines — use `lineHeight` to size each line.
|
|
10
|
+
*/
|
|
5
11
|
height?: string | number;
|
|
12
|
+
/**
|
|
13
|
+
* Height of each line in the multi-line text variant (`variant="text"`
|
|
14
|
+
* with `lines > 1`). Falls back to the `.text` class height (1rem) when
|
|
15
|
+
* omitted. Ignored by the single-bar variants — use `height` there.
|
|
16
|
+
*/
|
|
17
|
+
lineHeight?: string | number;
|
|
6
18
|
borderRadius?: string;
|
|
7
19
|
variant?: 'text' | 'rectangular' | 'circular';
|
|
8
20
|
lines?: number;
|
|
9
21
|
children?: React.ReactNode;
|
|
10
22
|
}
|
|
11
|
-
export declare function Shimmer({ className, width, height, borderRadius, variant, lines, children, ...other }: ShimmerProps): React.JSX.Element;
|
|
23
|
+
export declare function Shimmer({ className, width, height, lineHeight, borderRadius, variant, lines, children, ...other }: ShimmerProps): React.JSX.Element;
|
|
12
24
|
export {};
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import classnames from "classnames";
|
|
3
3
|
import shimmer_module from "./shimmer.module.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
width: 'number' == typeof width ? `${width}px` : width,
|
|
7
|
-
height: 'number' == typeof height ? `${height}px` : height,
|
|
8
|
-
borderRadius: borderRadius
|
|
9
|
-
};
|
|
4
|
+
const toCssSize = (value)=>'number' == typeof value ? `${value}px` : value;
|
|
5
|
+
function Shimmer({ className, width = '100%', height, lineHeight, borderRadius, variant = 'rectangular', lines = 1, children, ...other }) {
|
|
10
6
|
const getVariantClass = ()=>{
|
|
11
7
|
switch(variant){
|
|
12
8
|
case 'text':
|
|
@@ -17,20 +13,33 @@ function Shimmer({ className, width = '100%', height = '1rem', borderRadius, var
|
|
|
17
13
|
return shimmer_module.rectangular;
|
|
18
14
|
}
|
|
19
15
|
};
|
|
20
|
-
if ('text' === variant && lines > 1)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
16
|
+
if ('text' === variant && lines > 1) {
|
|
17
|
+
const resolvedLineHeight = toCssSize(lineHeight);
|
|
18
|
+
return /*#__PURE__*/ jsx("div", {
|
|
19
|
+
className: classnames(shimmer_module.shimmerContainer, className),
|
|
20
|
+
style: {
|
|
21
|
+
width: toCssSize(width),
|
|
22
|
+
height: toCssSize(height)
|
|
23
|
+
},
|
|
24
|
+
...other,
|
|
25
|
+
children: Array.from({
|
|
26
|
+
length: lines
|
|
27
|
+
}, (_, index)=>/*#__PURE__*/ jsx("div", {
|
|
28
|
+
className: classnames(shimmer_module.shimmer, shimmer_module.text),
|
|
29
|
+
style: {
|
|
30
|
+
width: index === lines - 1 ? '75%' : '100%',
|
|
31
|
+
height: resolvedLineHeight,
|
|
32
|
+
borderRadius,
|
|
33
|
+
marginBottom: index === lines - 1 ? 0 : '0.5rem'
|
|
34
|
+
}
|
|
35
|
+
}, `shimmer-line-${index}`))
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
const shimmerStyle = {
|
|
39
|
+
width: toCssSize(width),
|
|
40
|
+
height: toCssSize(height) ?? '1rem',
|
|
41
|
+
borderRadius
|
|
42
|
+
};
|
|
34
43
|
return /*#__PURE__*/ jsx("div", {
|
|
35
44
|
className: classnames(shimmer_module.shimmer, getVariantClass(), className),
|
|
36
45
|
style: shimmerStyle,
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
@layer byline-components {
|
|
4
4
|
:is(.shimmer-hQj5gn, .byline-shimmer) {
|
|
5
|
-
background-color:
|
|
6
|
-
background-image: linear-gradient(90deg, #0000, #
|
|
5
|
+
background-color: var(--surface-shimmer);
|
|
6
|
+
background-image: linear-gradient(90deg, #0000, #ffffffb3, #0000);
|
|
7
7
|
background-size: 200% 100%;
|
|
8
8
|
animation: 1.5s infinite shimmer-hQj5gn;
|
|
9
9
|
position: relative;
|
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
:is(:is(.dark, [data-theme="dark"]) .shimmer-hQj5gn, :is(.dark, [data-theme="dark"]) .byline-shimmer) {
|
|
14
|
-
background-
|
|
15
|
-
background-image: linear-gradient(90deg, #0000, #ffffff03, #0000);
|
|
14
|
+
background-image: linear-gradient(90deg, #0000, #ffffff0a, #0000);
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
:is(.shimmerContainer-YqBAXa, .byline-shimmer-container) {
|
|
19
18
|
flex-direction: column;
|
|
20
19
|
display: flex;
|
|
20
|
+
overflow: hidden;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
:is(.rectangular-qx6oTl, .byline-shimmer-rectangular) {
|
package/dist/styles/styles.css
CHANGED
|
@@ -1314,6 +1314,7 @@
|
|
|
1314
1314
|
--surface-subtle: var(--canvas-50);
|
|
1315
1315
|
--surface-subtle-hover: var(--canvas-100);
|
|
1316
1316
|
--surface-subtle-active: var(--canvas-200);
|
|
1317
|
+
--surface-shimmer: var(--canvas-100);
|
|
1317
1318
|
--surface-panel-scrollbar: var(--gray-50);
|
|
1318
1319
|
--surface-panel-scrollbar-thumb: var(--primary-100);
|
|
1319
1320
|
}
|
|
@@ -1336,6 +1337,7 @@
|
|
|
1336
1337
|
--surface-subtle: var(--canvas-800);
|
|
1337
1338
|
--surface-subtle-hover: var(--canvas-700);
|
|
1338
1339
|
--surface-subtle-active: var(--canvas-600);
|
|
1340
|
+
--surface-shimmer: oklch(from var(--canvas-base) calc(l * .45) c h);
|
|
1339
1341
|
--surface-panel-scrollbar: var(--canvas-700);
|
|
1340
1342
|
--surface-panel-scrollbar-thumb: var(--primary-400);
|
|
1341
1343
|
}
|
|
@@ -1358,6 +1360,7 @@
|
|
|
1358
1360
|
--surface-subtle: var(--canvas-50);
|
|
1359
1361
|
--surface-subtle-hover: var(--canvas-100);
|
|
1360
1362
|
--surface-subtle-active: var(--canvas-200);
|
|
1363
|
+
--surface-shimmer: var(--canvas-100);
|
|
1361
1364
|
--surface-panel-scrollbar: var(--gray-50);
|
|
1362
1365
|
--surface-panel-scrollbar-thumb: var(--primary-100);
|
|
1363
1366
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"private": false,
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
|
-
"version": "2.
|
|
6
|
+
"version": "2.7.0",
|
|
7
7
|
"engines": {
|
|
8
8
|
"node": ">=20.9.0"
|
|
9
9
|
},
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"npm-run-all": "^4.1.5",
|
|
63
63
|
"react-day-picker": "^10.0.1",
|
|
64
64
|
"zod": "^4.4.3",
|
|
65
|
-
"@byline/core": "2.
|
|
65
|
+
"@byline/core": "2.7.0"
|
|
66
66
|
},
|
|
67
67
|
"peerDependencies": {
|
|
68
68
|
"react": "^19.0.0",
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
:global(.byline-shimmer) {
|
|
16
16
|
position: relative;
|
|
17
17
|
overflow: hidden;
|
|
18
|
-
background-color:
|
|
19
|
-
background-image: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.
|
|
18
|
+
background-color: var(--surface-shimmer);
|
|
19
|
+
background-image: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.7), transparent);
|
|
20
20
|
background-size: 200% 100%;
|
|
21
21
|
animation: shimmer 1.5s infinite;
|
|
22
22
|
}
|
|
@@ -25,8 +25,9 @@
|
|
|
25
25
|
:global([data-theme="dark"]) {
|
|
26
26
|
.shimmer,
|
|
27
27
|
:global(.byline-shimmer) {
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
/* base colour comes from --surface-shimmer; only the white sheen is
|
|
29
|
+
toned down here so it doesn't glare against the dark bar */
|
|
30
|
+
background-image: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.04), transparent);
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
33
|
|
|
@@ -34,6 +35,9 @@
|
|
|
34
35
|
:global(.byline-shimmer-container) {
|
|
35
36
|
display: flex;
|
|
36
37
|
flex-direction: column;
|
|
38
|
+
/* When a container `height` is set, crop overflowing lines cleanly
|
|
39
|
+
rather than letting them spill past the skeleton's bounds. */
|
|
40
|
+
overflow: hidden;
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
.rectangular,
|
|
@@ -7,29 +7,39 @@ import styles from './shimmer.module.css'
|
|
|
7
7
|
interface ShimmerProps {
|
|
8
8
|
className?: string
|
|
9
9
|
width?: string | number
|
|
10
|
+
/**
|
|
11
|
+
* Height of the bar. For the single-bar variants (`rectangular`,
|
|
12
|
+
* `circular`, and single-line `text`) this sizes the bar itself. For the
|
|
13
|
+
* multi-line text variant (`variant="text"` with `lines > 1`) it sizes the
|
|
14
|
+
* container that holds the lines — use `lineHeight` to size each line.
|
|
15
|
+
*/
|
|
10
16
|
height?: string | number
|
|
17
|
+
/**
|
|
18
|
+
* Height of each line in the multi-line text variant (`variant="text"`
|
|
19
|
+
* with `lines > 1`). Falls back to the `.text` class height (1rem) when
|
|
20
|
+
* omitted. Ignored by the single-bar variants — use `height` there.
|
|
21
|
+
*/
|
|
22
|
+
lineHeight?: string | number
|
|
11
23
|
borderRadius?: string
|
|
12
24
|
variant?: 'text' | 'rectangular' | 'circular'
|
|
13
25
|
lines?: number
|
|
14
26
|
children?: React.ReactNode
|
|
15
27
|
}
|
|
16
28
|
|
|
29
|
+
const toCssSize = (value: string | number | undefined): string | undefined =>
|
|
30
|
+
typeof value === 'number' ? `${value}px` : value
|
|
31
|
+
|
|
17
32
|
export function Shimmer({
|
|
18
33
|
className,
|
|
19
34
|
width = '100%',
|
|
20
|
-
height
|
|
35
|
+
height,
|
|
36
|
+
lineHeight,
|
|
21
37
|
borderRadius,
|
|
22
38
|
variant = 'rectangular',
|
|
23
39
|
lines = 1,
|
|
24
40
|
children,
|
|
25
41
|
...other
|
|
26
42
|
}: ShimmerProps): React.JSX.Element {
|
|
27
|
-
const shimmerStyle = {
|
|
28
|
-
width: typeof width === 'number' ? `${width}px` : width,
|
|
29
|
-
height: typeof height === 'number' ? `${height}px` : height,
|
|
30
|
-
borderRadius: borderRadius,
|
|
31
|
-
}
|
|
32
|
-
|
|
33
43
|
const getVariantClass = () => {
|
|
34
44
|
switch (variant) {
|
|
35
45
|
case 'text':
|
|
@@ -42,15 +52,24 @@ export function Shimmer({
|
|
|
42
52
|
}
|
|
43
53
|
|
|
44
54
|
if (variant === 'text' && lines > 1) {
|
|
55
|
+
// `height` sizes the container; each line is sized by `lineHeight`
|
|
56
|
+
// (undefined falls through to the `.text` class height). `height` is
|
|
57
|
+
// deliberately not spread onto the lines so it can't distort them.
|
|
58
|
+
const resolvedLineHeight = toCssSize(lineHeight)
|
|
45
59
|
return (
|
|
46
|
-
<div
|
|
60
|
+
<div
|
|
61
|
+
className={cx(styles.shimmerContainer, className)}
|
|
62
|
+
style={{ width: toCssSize(width), height: toCssSize(height) }}
|
|
63
|
+
{...other}
|
|
64
|
+
>
|
|
47
65
|
{Array.from({ length: lines }, (_, index) => (
|
|
48
66
|
<div
|
|
49
67
|
key={`shimmer-line-${index}`}
|
|
50
68
|
className={cx(styles.shimmer, styles.text)}
|
|
51
69
|
style={{
|
|
52
|
-
...shimmerStyle,
|
|
53
70
|
width: index === lines - 1 ? '75%' : '100%',
|
|
71
|
+
height: resolvedLineHeight,
|
|
72
|
+
borderRadius,
|
|
54
73
|
marginBottom: index === lines - 1 ? 0 : '0.5rem',
|
|
55
74
|
}}
|
|
56
75
|
/>
|
|
@@ -59,6 +78,12 @@ export function Shimmer({
|
|
|
59
78
|
)
|
|
60
79
|
}
|
|
61
80
|
|
|
81
|
+
const shimmerStyle = {
|
|
82
|
+
width: toCssSize(width),
|
|
83
|
+
height: toCssSize(height) ?? '1rem',
|
|
84
|
+
borderRadius,
|
|
85
|
+
}
|
|
86
|
+
|
|
62
87
|
return (
|
|
63
88
|
<div
|
|
64
89
|
className={cx(styles.shimmer, getVariantClass(), className)}
|
|
@@ -39,12 +39,16 @@
|
|
|
39
39
|
--surface-subtle-hover: var(--canvas-100);
|
|
40
40
|
--surface-subtle-active: var(--canvas-200);
|
|
41
41
|
|
|
42
|
+
/* Shimmer / skeleton placeholder bar — sits a step darker than the
|
|
43
|
+
panel so loading lines read clearly on a light surface. */
|
|
44
|
+
--surface-shimmer: var(--canvas-100);
|
|
45
|
+
|
|
42
46
|
/* Panel scrollers */
|
|
43
47
|
--surface-panel-scrollbar: var(--gray-50);
|
|
44
48
|
--surface-panel-scrollbar-thumb: var(--primary-100);
|
|
45
49
|
}
|
|
46
50
|
|
|
47
|
-
/* 🌙 Dark via `.dark` class or [data-theme="dark"] attribute.
|
|
51
|
+
/* 🌙 Dark via `.dark` class or [data-theme="dark"] attribute.
|
|
48
52
|
* We rely on the consuming application to detect a user's
|
|
49
53
|
* preferred color scheme - either by header or cookie, and to set
|
|
50
54
|
* a root html class accordingly (for now), which unfortunately means
|
|
@@ -83,6 +87,11 @@
|
|
|
83
87
|
--surface-subtle-hover: var(--canvas-700);
|
|
84
88
|
--surface-subtle-active: var(--canvas-600);
|
|
85
89
|
|
|
90
|
+
/* Shimmer / skeleton placeholder bar — lifted just above the panel so
|
|
91
|
+
loading lines are visible without glaring on a dark surface. Sits
|
|
92
|
+
between canvas-800 (panel) and canvas-700 (hover). */
|
|
93
|
+
--surface-shimmer: oklch(from var(--canvas-base) calc(l * 0.45) c h);
|
|
94
|
+
|
|
86
95
|
/* Panel scrollers */
|
|
87
96
|
--surface-panel-scrollbar: var(--canvas-700);
|
|
88
97
|
--surface-panel-scrollbar-thumb: var(--primary-400);
|
|
@@ -125,6 +134,9 @@
|
|
|
125
134
|
--surface-subtle-hover: var(--canvas-100);
|
|
126
135
|
--surface-subtle-active: var(--canvas-200);
|
|
127
136
|
|
|
137
|
+
/* Shimmer / skeleton placeholder bar */
|
|
138
|
+
--surface-shimmer: var(--canvas-100);
|
|
139
|
+
|
|
128
140
|
/* Panel scrollers */
|
|
129
141
|
--surface-panel-scrollbar: var(--gray-50);
|
|
130
142
|
--surface-panel-scrollbar-thumb: var(--primary-100);
|