gbs-add-block 1.2.19 → 2.0.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/README.md +4 -4
- package/index.cjs +25 -9
- package/package.json +1 -1
- package/source/beta-components/accordion/README.md +45 -0
- package/source/beta-components/accordion/__tests__/core.test.ts +58 -0
- package/source/beta-components/accordion/core/index.ts +2 -0
- package/source/beta-components/accordion/core/open.ts +56 -0
- package/source/beta-components/accordion/core/types.ts +17 -0
- package/source/beta-components/accordion/index.ts +8 -0
- package/source/beta-components/accordion/react/Accordion.tsx +133 -0
- package/source/beta-components/accordion/react/AccordionItem.tsx +120 -0
- package/source/beta-components/accordion/react/context.ts +20 -0
- package/source/beta-components/accordion/react/props.ts +13 -0
- package/source/beta-components/accordion/styles.css +208 -0
- package/source/beta-components/alert/README.md +39 -0
- package/source/beta-components/alert/__tests__/core.test.ts +17 -0
- package/source/beta-components/alert/core/index.ts +2 -0
- package/source/beta-components/alert/core/live.ts +25 -0
- package/source/beta-components/alert/core/types.ts +7 -0
- package/source/beta-components/alert/index.ts +5 -0
- package/source/beta-components/alert/react/Alert.tsx +113 -0
- package/source/beta-components/alert/react/icons.tsx +21 -0
- package/source/beta-components/alert/react/locale.ts +5 -0
- package/source/beta-components/alert/react/props.ts +11 -0
- package/source/beta-components/alert/styles.css +155 -0
- package/source/beta-components/avatar/__tests__/core.test.ts +88 -0
- package/source/beta-components/avatar/core/identity.ts +103 -0
- package/source/beta-components/avatar/core/index.ts +2 -0
- package/source/beta-components/avatar/core/types.ts +12 -0
- package/source/beta-components/avatar/index.ts +7 -0
- package/source/beta-components/avatar/react/Avatar.tsx +118 -0
- package/source/beta-components/avatar/react/AvatarGroup.tsx +74 -0
- package/source/beta-components/avatar/react/locale.ts +11 -0
- package/source/beta-components/avatar/react/props.ts +6 -0
- package/source/beta-components/avatar/styles.css +227 -0
- package/source/beta-components/badge/README.md +37 -0
- package/source/beta-components/badge/__tests__/core.test.ts +46 -0
- package/source/beta-components/badge/core/count.ts +37 -0
- package/source/beta-components/badge/core/index.ts +2 -0
- package/source/beta-components/badge/core/types.ts +11 -0
- package/source/beta-components/badge/index.ts +7 -0
- package/source/beta-components/badge/react/Badge.tsx +89 -0
- package/source/beta-components/badge/react/Tag.tsx +82 -0
- package/source/beta-components/badge/react/locale.ts +5 -0
- package/source/beta-components/badge/react/props.ts +6 -0
- package/source/beta-components/badge/styles.css +204 -0
- package/source/beta-components/progress/README.md +38 -0
- package/source/beta-components/progress/__tests__/core.test.ts +56 -0
- package/source/beta-components/progress/core/index.ts +2 -0
- package/source/beta-components/progress/core/progress.ts +40 -0
- package/source/beta-components/progress/core/types.ts +23 -0
- package/source/beta-components/progress/index.ts +7 -0
- package/source/beta-components/progress/react/CircularProgress.tsx +106 -0
- package/source/beta-components/progress/react/Progress.tsx +113 -0
- package/source/beta-components/progress/react/locale.ts +7 -0
- package/source/beta-components/progress/react/props.ts +6 -0
- package/source/beta-components/progress/styles.css +202 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useId, useMemo, type CSSProperties, type ReactNode, type Ref } from "react";
|
|
4
|
+
import { describeProgress } from "../core/progress";
|
|
5
|
+
import type { ProgressLocaleText, ProgressVariant } from "../core/types";
|
|
6
|
+
import { defaultProgressText } from "./locale";
|
|
7
|
+
import { cx, type CircularProgressSlot } from "./props";
|
|
8
|
+
|
|
9
|
+
export interface CircularProgressProps {
|
|
10
|
+
value?: number | null;
|
|
11
|
+
max?: number;
|
|
12
|
+
/** Diameter in pixels. Default 44. */
|
|
13
|
+
size?: number;
|
|
14
|
+
/** Ring thickness in pixels. Default 4. */
|
|
15
|
+
thickness?: number;
|
|
16
|
+
variant?: ProgressVariant;
|
|
17
|
+
/** Names the ring for assistive technology. */
|
|
18
|
+
label?: string;
|
|
19
|
+
/** Print the percentage in the middle, or your own node. */
|
|
20
|
+
showValue?: boolean;
|
|
21
|
+
children?: ReactNode;
|
|
22
|
+
className?: string;
|
|
23
|
+
classNames?: Partial<Record<CircularProgressSlot, string>>;
|
|
24
|
+
style?: CSSProperties;
|
|
25
|
+
localeText?: Partial<ProgressLocaleText>;
|
|
26
|
+
ref?: Ref<HTMLDivElement>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The same progress as a ring, for a tile or a table cell where a bar would be
|
|
31
|
+
* too wide.
|
|
32
|
+
*
|
|
33
|
+
* The arc is one circle with a dashed stroke: the dash is the whole
|
|
34
|
+
* circumference, and the gap moves it — no arc paths, no trigonometry, and it
|
|
35
|
+
* scales with `size` without redrawing anything.
|
|
36
|
+
*/
|
|
37
|
+
export function CircularProgress(props: CircularProgressProps) {
|
|
38
|
+
const {
|
|
39
|
+
ref,
|
|
40
|
+
value = null,
|
|
41
|
+
max = 100,
|
|
42
|
+
size = 44,
|
|
43
|
+
thickness = 4,
|
|
44
|
+
variant = "accent",
|
|
45
|
+
label,
|
|
46
|
+
showValue = false,
|
|
47
|
+
children,
|
|
48
|
+
className,
|
|
49
|
+
classNames,
|
|
50
|
+
style,
|
|
51
|
+
localeText,
|
|
52
|
+
} = props;
|
|
53
|
+
|
|
54
|
+
const id = useId();
|
|
55
|
+
const text = useMemo(() => ({ ...defaultProgressText, ...localeText }), [localeText]);
|
|
56
|
+
const state = describeProgress(value, max);
|
|
57
|
+
|
|
58
|
+
const radius = (size - thickness) / 2;
|
|
59
|
+
const circumference = 2 * Math.PI * radius;
|
|
60
|
+
// An indeterminate ring shows a quarter arc that spins; a determinate one
|
|
61
|
+
// shows its fraction.
|
|
62
|
+
const filled = state.indeterminate ? 0.25 : state.fraction;
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<div
|
|
66
|
+
ref={ref}
|
|
67
|
+
className={cx("pr-circle", classNames?.root, className)}
|
|
68
|
+
style={{ ...style, width: size, height: size }}
|
|
69
|
+
data-variant={variant}
|
|
70
|
+
data-indeterminate={state.indeterminate || undefined}
|
|
71
|
+
role="progressbar"
|
|
72
|
+
aria-valuenow={state.indeterminate ? undefined : state.value ?? undefined}
|
|
73
|
+
aria-valuemin={state.indeterminate ? undefined : 0}
|
|
74
|
+
aria-valuemax={state.indeterminate ? undefined : max}
|
|
75
|
+
aria-valuetext={state.indeterminate ? undefined : text.valueText(state.percent)}
|
|
76
|
+
aria-label={label ?? text.label}
|
|
77
|
+
>
|
|
78
|
+
<svg className={cx("pr-svg", classNames?.svg)} viewBox={`0 0 ${size} ${size}`} aria-hidden="true">
|
|
79
|
+
<circle
|
|
80
|
+
className={cx("pr-circle-track", classNames?.track)}
|
|
81
|
+
cx={size / 2}
|
|
82
|
+
cy={size / 2}
|
|
83
|
+
r={radius}
|
|
84
|
+
fill="none"
|
|
85
|
+
strokeWidth={thickness}
|
|
86
|
+
/>
|
|
87
|
+
<circle
|
|
88
|
+
className={cx("pr-circle-bar", classNames?.bar)}
|
|
89
|
+
cx={size / 2}
|
|
90
|
+
cy={size / 2}
|
|
91
|
+
r={radius}
|
|
92
|
+
fill="none"
|
|
93
|
+
strokeWidth={thickness}
|
|
94
|
+
strokeLinecap="round"
|
|
95
|
+
strokeDasharray={circumference}
|
|
96
|
+
strokeDashoffset={circumference * (1 - filled)}
|
|
97
|
+
/>
|
|
98
|
+
</svg>
|
|
99
|
+
{(showValue || children) && (
|
|
100
|
+
<span className={cx("pr-circle-label", classNames?.label)} aria-hidden="true" id={`${id}-label`}>
|
|
101
|
+
{children ?? (state.indeterminate ? "" : `${state.percent}%`)}
|
|
102
|
+
</span>
|
|
103
|
+
)}
|
|
104
|
+
</div>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
useId,
|
|
5
|
+
useMemo,
|
|
6
|
+
type CSSProperties,
|
|
7
|
+
type HTMLAttributes,
|
|
8
|
+
type ReactNode,
|
|
9
|
+
type Ref,
|
|
10
|
+
} from "react";
|
|
11
|
+
import { describeProgress } from "../core/progress";
|
|
12
|
+
import type { ProgressLocaleText, ProgressSize, ProgressVariant } from "../core/types";
|
|
13
|
+
import { defaultProgressText } from "./locale";
|
|
14
|
+
import { cx, type ProgressSlot } from "./props";
|
|
15
|
+
|
|
16
|
+
export interface ProgressProps extends Omit<HTMLAttributes<HTMLDivElement>, "role"> {
|
|
17
|
+
/** How far along. `null` means the length is not known yet. */
|
|
18
|
+
value?: number | null;
|
|
19
|
+
/** What `value` is measured against. Default 100. */
|
|
20
|
+
max?: number;
|
|
21
|
+
/** Names the bar. Shown above it, and used as the accessible name. */
|
|
22
|
+
label?: ReactNode;
|
|
23
|
+
/** Show the percentage beside the label. */
|
|
24
|
+
showValue?: boolean;
|
|
25
|
+
/** Replace what is shown and read, e.g. "3.2 MB of 8 MB". */
|
|
26
|
+
valueText?: ReactNode;
|
|
27
|
+
/** Default `accent`. */
|
|
28
|
+
variant?: ProgressVariant;
|
|
29
|
+
/** Default `md`. */
|
|
30
|
+
size?: ProgressSize;
|
|
31
|
+
classNames?: Partial<Record<ProgressSlot, string>>;
|
|
32
|
+
localeText?: Partial<ProgressLocaleText>;
|
|
33
|
+
ref?: Ref<HTMLDivElement>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* A bar for something with a known end: an upload, an import, a quota.
|
|
38
|
+
*
|
|
39
|
+
* Use a **Spinner** when there is nothing to measure and nothing to say about
|
|
40
|
+
* how long it will take. A progress bar that spends its life indeterminate is
|
|
41
|
+
* a spinner drawn as a promise it cannot keep.
|
|
42
|
+
*/
|
|
43
|
+
export function Progress(props: ProgressProps) {
|
|
44
|
+
const {
|
|
45
|
+
ref,
|
|
46
|
+
value = null,
|
|
47
|
+
max = 100,
|
|
48
|
+
label,
|
|
49
|
+
showValue = false,
|
|
50
|
+
valueText,
|
|
51
|
+
variant = "accent",
|
|
52
|
+
size = "md",
|
|
53
|
+
className,
|
|
54
|
+
classNames,
|
|
55
|
+
style,
|
|
56
|
+
localeText,
|
|
57
|
+
id: idProp,
|
|
58
|
+
"aria-label": ariaLabel,
|
|
59
|
+
...rest
|
|
60
|
+
} = props;
|
|
61
|
+
|
|
62
|
+
const reactId = useId();
|
|
63
|
+
const id = idProp ?? reactId;
|
|
64
|
+
const text = useMemo(() => ({ ...defaultProgressText, ...localeText }), [localeText]);
|
|
65
|
+
const state = describeProgress(value, max);
|
|
66
|
+
const shown = valueText ?? (state.indeterminate ? text.working : text.valueText(state.percent));
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<div
|
|
70
|
+
{...rest}
|
|
71
|
+
ref={ref}
|
|
72
|
+
id={id}
|
|
73
|
+
className={cx("pr-root", classNames?.root, className)}
|
|
74
|
+
style={style}
|
|
75
|
+
data-variant={variant}
|
|
76
|
+
data-size={size}
|
|
77
|
+
data-indeterminate={state.indeterminate || undefined}
|
|
78
|
+
>
|
|
79
|
+
{(label || showValue) && (
|
|
80
|
+
<div className={cx("pr-header", classNames?.header)}>
|
|
81
|
+
{label && (
|
|
82
|
+
<span id={`${id}-label`} className={cx("pr-label", classNames?.label)}>
|
|
83
|
+
{label}
|
|
84
|
+
</span>
|
|
85
|
+
)}
|
|
86
|
+
{showValue && <span className={cx("pr-value", classNames?.value)}>{shown}</span>}
|
|
87
|
+
</div>
|
|
88
|
+
)}
|
|
89
|
+
|
|
90
|
+
<div
|
|
91
|
+
className={cx("pr-track", classNames?.track)}
|
|
92
|
+
role="progressbar"
|
|
93
|
+
// No aria-valuenow at all while the length is unknown: that is what
|
|
94
|
+
// tells a screen reader to say "busy" rather than to read out a zero.
|
|
95
|
+
aria-valuenow={state.indeterminate ? undefined : state.value ?? undefined}
|
|
96
|
+
aria-valuemin={state.indeterminate ? undefined : 0}
|
|
97
|
+
aria-valuemax={state.indeterminate ? undefined : max}
|
|
98
|
+
aria-valuetext={state.indeterminate ? undefined : typeof shown === "string" ? shown : undefined}
|
|
99
|
+
// The visible label names the bar when there is one, so the name and
|
|
100
|
+
// what is on screen can never drift apart.
|
|
101
|
+
aria-labelledby={label ? `${id}-label` : undefined}
|
|
102
|
+
aria-label={label ? undefined : (ariaLabel ?? text.label)}
|
|
103
|
+
>
|
|
104
|
+
<div
|
|
105
|
+
className={cx("pr-bar", classNames?.bar)}
|
|
106
|
+
// Drawn from the unrounded fraction, so the bar does not reach the
|
|
107
|
+
// end while the last of the work is still going.
|
|
108
|
+
style={{ "--pr-fraction": state.fraction } as CSSProperties}
|
|
109
|
+
/>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type ProgressSlot = "root" | "header" | "label" | "value" | "track" | "bar";
|
|
2
|
+
|
|
3
|
+
export type CircularProgressSlot = "root" | "svg" | "track" | "bar" | "label";
|
|
4
|
+
|
|
5
|
+
// Shared with every other component, so class handling cannot drift.
|
|
6
|
+
export { cx } from "../../shared/core/cx";
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Progress and CircularProgress styles.
|
|
3
|
+
*
|
|
4
|
+
* The bar is drawn from --pr-fraction (0 to 1) rather than a width in percent,
|
|
5
|
+
* so the same number drives the bar, the ring and any transition. Tokens read
|
|
6
|
+
* the shared --gbs-* variables when they are set on an ancestor (set them on
|
|
7
|
+
* :root to theme every component at once). Rules live in the `components`
|
|
8
|
+
* layer, so utility classes passed through `className` / `classNames` override
|
|
9
|
+
* them.
|
|
10
|
+
*/
|
|
11
|
+
@layer theme, base, components, utilities;
|
|
12
|
+
|
|
13
|
+
@layer components {
|
|
14
|
+
.pr-root,
|
|
15
|
+
.pr-circle {
|
|
16
|
+
--pr-fg: var(--gbs-fg, var(--dg-fg, light-dark(#18181b, #f4f4f5)));
|
|
17
|
+
--pr-muted: var(--gbs-muted, var(--dg-muted, light-dark(#71717a, #a1a1aa)));
|
|
18
|
+
--pr-track: var(--gbs-subtle, light-dark(#e4e4e7, #27272a));
|
|
19
|
+
--pr-accent: var(--gbs-accent, var(--dg-accent, light-dark(#2563eb, #60a5fa)));
|
|
20
|
+
--pr-success: var(--gbs-success, light-dark(#15803d, #4ade80));
|
|
21
|
+
--pr-warning: var(--gbs-warning, light-dark(#b45309, #fbbf24));
|
|
22
|
+
--pr-danger: var(--gbs-danger, var(--dg-danger, light-dark(#dc2626, #f87171)));
|
|
23
|
+
--pr-font-size: var(--gbs-font-size, var(--dg-font-size, 13px));
|
|
24
|
+
--pr-height: 8px;
|
|
25
|
+
--pr-duration: 240ms;
|
|
26
|
+
--pr-bar: var(--pr-accent);
|
|
27
|
+
|
|
28
|
+
color-scheme: inherit;
|
|
29
|
+
font-size: var(--pr-font-size);
|
|
30
|
+
color: var(--pr-fg);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
:where(.dark, [data-theme="dark"]) :is(.pr-root, .pr-circle) {
|
|
34
|
+
color-scheme: dark;
|
|
35
|
+
}
|
|
36
|
+
:where(.light, [data-theme="light"]) :is(.pr-root, .pr-circle) {
|
|
37
|
+
color-scheme: light;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
:where(.pr-root, .pr-circle) *,
|
|
41
|
+
:where(.pr-root, .pr-circle) *::before,
|
|
42
|
+
:where(.pr-root, .pr-circle) *::after {
|
|
43
|
+
box-sizing: border-box;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.pr-root[data-variant="success"],
|
|
47
|
+
.pr-circle[data-variant="success"] {
|
|
48
|
+
--pr-bar: var(--pr-success);
|
|
49
|
+
}
|
|
50
|
+
.pr-root[data-variant="warning"],
|
|
51
|
+
.pr-circle[data-variant="warning"] {
|
|
52
|
+
--pr-bar: var(--pr-warning);
|
|
53
|
+
}
|
|
54
|
+
.pr-root[data-variant="danger"],
|
|
55
|
+
.pr-circle[data-variant="danger"] {
|
|
56
|
+
--pr-bar: var(--pr-danger);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/* ------------------------------------------------------------------ bar */
|
|
60
|
+
|
|
61
|
+
.pr-root {
|
|
62
|
+
display: flex;
|
|
63
|
+
flex-direction: column;
|
|
64
|
+
gap: 6px;
|
|
65
|
+
min-width: 0;
|
|
66
|
+
}
|
|
67
|
+
.pr-root[data-size="sm"] {
|
|
68
|
+
--pr-height: 4px;
|
|
69
|
+
--pr-font-size: 12px;
|
|
70
|
+
}
|
|
71
|
+
.pr-root[data-size="lg"] {
|
|
72
|
+
--pr-height: 12px;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.pr-header {
|
|
76
|
+
display: flex;
|
|
77
|
+
align-items: baseline;
|
|
78
|
+
justify-content: space-between;
|
|
79
|
+
gap: 12px;
|
|
80
|
+
min-width: 0;
|
|
81
|
+
}
|
|
82
|
+
.pr-label {
|
|
83
|
+
overflow: hidden;
|
|
84
|
+
font-weight: 500;
|
|
85
|
+
text-overflow: ellipsis;
|
|
86
|
+
white-space: nowrap;
|
|
87
|
+
}
|
|
88
|
+
.pr-value {
|
|
89
|
+
flex: none;
|
|
90
|
+
color: var(--pr-muted);
|
|
91
|
+
font-variant-numeric: tabular-nums;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.pr-track {
|
|
95
|
+
position: relative;
|
|
96
|
+
width: 100%;
|
|
97
|
+
height: var(--pr-height);
|
|
98
|
+
border-radius: 999px;
|
|
99
|
+
background: var(--pr-track);
|
|
100
|
+
overflow: hidden;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.pr-bar {
|
|
104
|
+
width: 100%;
|
|
105
|
+
height: 100%;
|
|
106
|
+
border-radius: inherit;
|
|
107
|
+
background: var(--pr-bar);
|
|
108
|
+
/* `scaleX` from the origin: the compositor handles it, so a bar that ticks
|
|
109
|
+
up every few milliseconds costs nothing in layout. */
|
|
110
|
+
transform-origin: left center;
|
|
111
|
+
scale: var(--pr-fraction, 0) 1;
|
|
112
|
+
transition: scale var(--pr-duration) ease;
|
|
113
|
+
}
|
|
114
|
+
.pr-root:dir(rtl) .pr-bar {
|
|
115
|
+
transform-origin: right center;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* With no length to show, a short bar sweeps the track instead. */
|
|
119
|
+
.pr-root[data-indeterminate] .pr-bar {
|
|
120
|
+
width: 35%;
|
|
121
|
+
scale: 1 1;
|
|
122
|
+
animation: pr-sweep 1.3s ease-in-out infinite;
|
|
123
|
+
}
|
|
124
|
+
@keyframes pr-sweep {
|
|
125
|
+
from {
|
|
126
|
+
translate: -100%;
|
|
127
|
+
}
|
|
128
|
+
to {
|
|
129
|
+
translate: 300%;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/* ----------------------------------------------------------------- ring */
|
|
134
|
+
|
|
135
|
+
.pr-circle {
|
|
136
|
+
position: relative;
|
|
137
|
+
display: inline-flex;
|
|
138
|
+
flex: none;
|
|
139
|
+
align-items: center;
|
|
140
|
+
justify-content: center;
|
|
141
|
+
vertical-align: middle;
|
|
142
|
+
}
|
|
143
|
+
.pr-svg {
|
|
144
|
+
width: 100%;
|
|
145
|
+
height: 100%;
|
|
146
|
+
/* Zero is at three o'clock in SVG; a progress ring starts at the top. */
|
|
147
|
+
rotate: -90deg;
|
|
148
|
+
}
|
|
149
|
+
.pr-circle-track {
|
|
150
|
+
stroke: var(--pr-track);
|
|
151
|
+
}
|
|
152
|
+
.pr-circle-bar {
|
|
153
|
+
stroke: var(--pr-bar);
|
|
154
|
+
transition: stroke-dashoffset var(--pr-duration) ease;
|
|
155
|
+
}
|
|
156
|
+
.pr-circle[data-indeterminate] .pr-svg {
|
|
157
|
+
animation: pr-spin 1s linear infinite;
|
|
158
|
+
}
|
|
159
|
+
@keyframes pr-spin {
|
|
160
|
+
from {
|
|
161
|
+
rotate: -90deg;
|
|
162
|
+
}
|
|
163
|
+
to {
|
|
164
|
+
rotate: 270deg;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.pr-circle-label {
|
|
169
|
+
position: absolute;
|
|
170
|
+
font-size: calc(var(--pr-font-size) - 1px);
|
|
171
|
+
font-variant-numeric: tabular-nums;
|
|
172
|
+
font-weight: 600;
|
|
173
|
+
line-height: 1;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
@media (prefers-reduced-motion: reduce) {
|
|
177
|
+
.pr-bar,
|
|
178
|
+
.pr-circle-bar {
|
|
179
|
+
transition: none;
|
|
180
|
+
}
|
|
181
|
+
/* Movement that repeats forever is what reduced motion is about, but a
|
|
182
|
+
stopped indeterminate bar would look broken — so it slows instead. */
|
|
183
|
+
.pr-root[data-indeterminate] .pr-bar {
|
|
184
|
+
animation-duration: 3s;
|
|
185
|
+
}
|
|
186
|
+
.pr-circle[data-indeterminate] .pr-svg {
|
|
187
|
+
animation-duration: 2.5s;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
@media (forced-colors: active) {
|
|
192
|
+
.pr-track {
|
|
193
|
+
border: 1px solid CanvasText;
|
|
194
|
+
}
|
|
195
|
+
.pr-bar {
|
|
196
|
+
background: Highlight;
|
|
197
|
+
}
|
|
198
|
+
.pr-circle-bar {
|
|
199
|
+
stroke: Highlight;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|