@rojaostudio/ds 2.0.0-next.23 → 2.0.0-next.24
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/index.d.ts +1 -0
- package/dist/components/index.js +2 -0
- package/dist/components/loading-overlay.d.ts +43 -0
- package/dist/components/loading-overlay.js +81 -0
- package/dist/components/saving-bar.d.ts +15 -5
- package/dist/components/saving-bar.js +4 -4
- package/package.json +1 -1
- package/styles/rds/components-styles.css +76 -26
- package/styles/rds/components.css +6 -3
|
@@ -4,6 +4,7 @@ export { HoverCard, HoverCardProps } from './hover-card.js';
|
|
|
4
4
|
export { Dialog, DialogClose, DialogProps, DialogSize } from './dialog.js';
|
|
5
5
|
export { Sheet, SheetClose, SheetProps, SheetSide } from './sheet.js';
|
|
6
6
|
export { Drawer, DrawerClose, DrawerProps } from './drawer.js';
|
|
7
|
+
export { LoadingOverlay, LoadingOverlayProps } from './loading-overlay.js';
|
|
7
8
|
export { DropdownMenu, DropdownMenuAlign, DropdownMenuItem, DropdownMenuItemProps, DropdownMenuItemTone, DropdownMenuProps, DropdownMenuRadioGroup, DropdownMenuRadioGroupProps, DropdownMenuRadioItem, DropdownMenuRadioItemProps, DropdownMenuSeparator, DropdownMenuSide } from './dropdown-menu.js';
|
|
8
9
|
export { ContextMenu, ContextMenuItem, ContextMenuItemProps, ContextMenuItemTone, ContextMenuProps, ContextMenuSeparator } from './context-menu.js';
|
|
9
10
|
export { Command, CommandGroup, CommandGroupProps, CommandItem, CommandItemProps, CommandProps } from './command.js';
|
package/dist/components/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { HoverCard } from "./hover-card.js";
|
|
|
5
5
|
import { Dialog, DialogClose } from "./dialog.js";
|
|
6
6
|
import { Sheet, SheetClose } from "./sheet.js";
|
|
7
7
|
import { Drawer, DrawerClose } from "./drawer.js";
|
|
8
|
+
import { LoadingOverlay } from "./loading-overlay.js";
|
|
8
9
|
import {
|
|
9
10
|
DropdownMenu,
|
|
10
11
|
DropdownMenuItem,
|
|
@@ -223,6 +224,7 @@ export {
|
|
|
223
224
|
KbdGroup,
|
|
224
225
|
Listbox,
|
|
225
226
|
ListboxOption,
|
|
227
|
+
LoadingOverlay,
|
|
226
228
|
Marker,
|
|
227
229
|
MediaTile,
|
|
228
230
|
Message,
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { HTMLAttributes } from 'react';
|
|
3
|
+
|
|
4
|
+
interface LoadingOverlayProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
5
|
+
/**
|
|
6
|
+
* The action is running (Figma: `open`, code only). The overlay shows only if it is still true after `delay`:
|
|
7
|
+
* if the next page opens first, it never shows.
|
|
8
|
+
*/
|
|
9
|
+
open: boolean;
|
|
10
|
+
/** What is happening, in the gerund with its object: "Criando o produto…" (Figma: `label`). It is the dialog's name and is said once (aria-live="polite"). */
|
|
11
|
+
label?: string;
|
|
12
|
+
/**
|
|
13
|
+
* How long (ms) `open` has to stay true before the overlay shows. Up to it, the wait is the main button in
|
|
14
|
+
* loading (`<Button loading>`, or the SavingBar in `status="saving"`); past it, the overlay comes in and stays
|
|
15
|
+
* until the other page opens. 400 by default; 0 shows it at once.
|
|
16
|
+
*/
|
|
17
|
+
delay?: number;
|
|
18
|
+
/** Where the portal goes (default: document.body). Inside a `.ds-plate`, for example, to read the brand mode. */
|
|
19
|
+
container?: HTMLElement | null;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* LoadingOverlay — Figma [RDS] Overlays/LoadingOverlay. The long wait of an action that leads to another page
|
|
23
|
+
* (create the product and land on its editing). A veil over the whole screen (loading-overlay/scrim) and, in the
|
|
24
|
+
* middle, a panel (loading-overlay/background, radius/container, elevation/modal) with the Spinner lg and one line
|
|
25
|
+
* saying what is happening. Styles: loading-overlay.css.
|
|
26
|
+
*
|
|
27
|
+
* Time: up to `delay` (~400 ms) only the main button is in loading ("Criando…", aria-busy on the button); past it,
|
|
28
|
+
* the overlay shows, and it stays until the other page opens. If the navigation comes first, it never shows. Do not
|
|
29
|
+
* use it for short waits (it only flashes), to load a page or a list (PageSkeleton), for a measured wait (Progress),
|
|
30
|
+
* or to save without changing page (the SavingBar in `status="saving"`). Never two indicators: with the overlay,
|
|
31
|
+
* the SavingBar keeps only its button in loading.
|
|
32
|
+
*
|
|
33
|
+
* Error: the app sets `open={false}` (the overlay leaves and the focus goes back to where it was, the main button)
|
|
34
|
+
* and returns the error to the SavingBar in `status="error"`, with the form untouched.
|
|
35
|
+
*
|
|
36
|
+
* Accessibility: role="dialog" aria-modal="true" named by `label`; the focus goes to the panel (tabindex=-1) and
|
|
37
|
+
* stays there; Escape does not close it (the action is running). While it is shown, the rest of the page is
|
|
38
|
+
* `inert` and `aria-busy="true"` (put back on close). The label is in an aria-live="polite" region. With
|
|
39
|
+
* prefers-reduced-motion: reduce, no fade, and the Spinner turns slowly (3 s a turn).
|
|
40
|
+
*/
|
|
41
|
+
declare function LoadingOverlay({ open, label, delay, container, className, ...rest }: LoadingOverlayProps): react.ReactPortal | null;
|
|
42
|
+
|
|
43
|
+
export { LoadingOverlay, type LoadingOverlayProps };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
__objRest,
|
|
4
|
+
__spreadProps,
|
|
5
|
+
__spreadValues
|
|
6
|
+
} from "../chunk-ORMEWXMH.js";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
9
|
+
import { createPortal } from "react-dom";
|
|
10
|
+
import { Spinner } from "./spinner.js";
|
|
11
|
+
function isolate(keep) {
|
|
12
|
+
const marked = [];
|
|
13
|
+
for (let node = keep; node && node !== document.body && node.parentElement; node = node.parentElement) {
|
|
14
|
+
for (const sibling of node.parentElement.children) {
|
|
15
|
+
if (sibling === node || sibling.hasAttribute("inert") || /^(SCRIPT|STYLE|LINK|TEMPLATE)$/.test(sibling.tagName)) continue;
|
|
16
|
+
marked.push({ el: sibling, inert: sibling.getAttribute("inert"), busy: sibling.getAttribute("aria-busy") });
|
|
17
|
+
sibling.setAttribute("inert", "");
|
|
18
|
+
sibling.setAttribute("aria-busy", "true");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return marked;
|
|
22
|
+
}
|
|
23
|
+
function restore(marked) {
|
|
24
|
+
for (const { el, inert, busy } of marked) {
|
|
25
|
+
if (inert === null) el.removeAttribute("inert");
|
|
26
|
+
else el.setAttribute("inert", inert);
|
|
27
|
+
if (busy === null) el.removeAttribute("aria-busy");
|
|
28
|
+
else el.setAttribute("aria-busy", busy);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function LoadingOverlay(_a) {
|
|
32
|
+
var _b = _a, { open, label = "Carregando\u2026", delay = 400, container, className } = _b, rest = __objRest(_b, ["open", "label", "delay", "container", "className"]);
|
|
33
|
+
const [shown, setShown] = useState(false);
|
|
34
|
+
const veil = useRef(null);
|
|
35
|
+
const panel = useRef(null);
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
if (!open) {
|
|
38
|
+
setShown(false);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (delay <= 0) {
|
|
42
|
+
setShown(true);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const timer = setTimeout(() => setShown(true), delay);
|
|
46
|
+
return () => clearTimeout(timer);
|
|
47
|
+
}, [open, delay]);
|
|
48
|
+
useLayoutEffect(() => {
|
|
49
|
+
if (!shown || !veil.current || !panel.current) return;
|
|
50
|
+
const previous = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
51
|
+
const marked = isolate(veil.current);
|
|
52
|
+
const box = panel.current;
|
|
53
|
+
box.focus({ preventScroll: true });
|
|
54
|
+
const keep = (event) => {
|
|
55
|
+
if (!box.contains(event.target)) box.focus({ preventScroll: true });
|
|
56
|
+
};
|
|
57
|
+
document.addEventListener("focusin", keep);
|
|
58
|
+
return () => {
|
|
59
|
+
document.removeEventListener("focusin", keep);
|
|
60
|
+
restore(marked);
|
|
61
|
+
if (previous == null ? void 0 : previous.isConnected) previous.focus({ preventScroll: true });
|
|
62
|
+
};
|
|
63
|
+
}, [shown]);
|
|
64
|
+
if (!shown || typeof document === "undefined") return null;
|
|
65
|
+
const onKeyDown = (event) => {
|
|
66
|
+
if (event.key === "Escape" || event.key === "Tab") {
|
|
67
|
+
event.preventDefault();
|
|
68
|
+
event.stopPropagation();
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
return createPortal(
|
|
72
|
+
/* @__PURE__ */ jsx("div", __spreadProps(__spreadValues({}, rest), { ref: veil, className: ["rds-loading-overlay", className].filter(Boolean).join(" "), onKeyDown, children: /* @__PURE__ */ jsxs("div", { ref: panel, className: "rds-loading-overlay__panel", role: "dialog", "aria-modal": "true", "aria-label": label, tabIndex: -1, children: [
|
|
73
|
+
/* @__PURE__ */ jsx(Spinner, { size: "lg", tone: "neutral", "aria-hidden": "true" }),
|
|
74
|
+
/* @__PURE__ */ jsx("p", { className: "rds-loading-overlay__label", "aria-live": "polite", children: label })
|
|
75
|
+
] }) })),
|
|
76
|
+
container != null ? container : document.body
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
export {
|
|
80
|
+
LoadingOverlay
|
|
81
|
+
};
|
|
@@ -4,19 +4,26 @@ import { HTMLAttributes, ReactNode } from 'react';
|
|
|
4
4
|
type SavingBarStatus = 'unsaved' | 'saving' | 'error';
|
|
5
5
|
interface SavingBarProps extends HTMLAttributes<HTMLDivElement> {
|
|
6
6
|
/**
|
|
7
|
-
* unsaved: the message and the actions; saving:
|
|
8
|
-
* error: an alert, `errorMessage`, and Salvar
|
|
7
|
+
* unsaved: the message and the actions; saving: `savingMessage`, Salvar in loading (`savingLabel`, the only
|
|
8
|
+
* indicator, no loader in the message) and Descartar disabled; error: an alert, `errorMessage`, and Salvar
|
|
9
|
+
* becomes `retryLabel` (Figma: `status`).
|
|
9
10
|
*/
|
|
10
11
|
status?: SavingBarStatus;
|
|
11
12
|
/** The unsaved text (Figma: `message`). */
|
|
12
13
|
message?: ReactNode;
|
|
13
14
|
/** The text while saving. */
|
|
14
15
|
savingMessage?: ReactNode;
|
|
16
|
+
/** Salvar's label while saving, in loading (`<Button loading>`), also announced. */
|
|
17
|
+
savingLabel?: string;
|
|
15
18
|
/** The error text. */
|
|
16
19
|
errorMessage?: ReactNode;
|
|
17
20
|
/** Called by Salvar (and by Tentar de novo, on error). */
|
|
18
21
|
onSave: () => void;
|
|
19
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Shows Descartar and is called when it is pressed (Figma: `showDiscard`). Expanded only: in the compact
|
|
24
|
+
* arrangement (the phone) the bar has only the main button, and Descartar belongs to the app, in the footer of
|
|
25
|
+
* the details Drawer or in the confirmation when leaving with changes (AlertDialog).
|
|
26
|
+
*/
|
|
20
27
|
onDiscard?: () => void;
|
|
21
28
|
saveLabel?: string;
|
|
22
29
|
retryLabel?: string;
|
|
@@ -38,8 +45,11 @@ interface SavingBarProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
38
45
|
* saved, and leaves once saved. It is the brand's primary colour (savingbar/background, colors/primary/default),
|
|
39
46
|
* in light and dark and in every brand: a state that waits for a decision, not a notice. It does not place itself:
|
|
40
47
|
* put it sticky or fixed at the bottom. Its Buttons are Salvar in tone action and Descartar in tone neutral ghost,
|
|
41
|
-
* with the bar's colours (savingbar/button/*).
|
|
48
|
+
* with the bar's colours (savingbar/button/*). Below 1024 (compact, the phone) it is one row, 64 tall plus the
|
|
49
|
+
* safe area: the message (or the details button) on the left and only Salvar on the right; Descartar is the app's
|
|
50
|
+
* there, in the footer of the details Drawer or in the confirmation when leaving. While saving, the indicator is
|
|
51
|
+
* Salvar in loading, alone (with the LoadingOverlay too). Styles: saving-bar.css.
|
|
42
52
|
*/
|
|
43
|
-
declare function SavingBar({ status, message, savingMessage, errorMessage, onSave, onDiscard, saveLabel, retryLabel, discardLabel, onDetails, detailsLabel, detailsExpanded, detailsControls, className, ...rest }: SavingBarProps): react.JSX.Element;
|
|
53
|
+
declare function SavingBar({ status, message, savingMessage, savingLabel, errorMessage, onSave, onDiscard, saveLabel, retryLabel, discardLabel, onDetails, detailsLabel, detailsExpanded, detailsControls, className, ...rest }: SavingBarProps): react.JSX.Element;
|
|
44
54
|
|
|
45
55
|
export { SavingBar, type SavingBarProps, type SavingBarStatus };
|
|
@@ -6,13 +6,13 @@ import {
|
|
|
6
6
|
} from "../chunk-ORMEWXMH.js";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { Button } from "./button.js";
|
|
9
|
-
import { Loader } from "./internal/button.js";
|
|
10
9
|
import { AlertIcon, ChevronUpIcon } from "./internal/icons.js";
|
|
11
10
|
function SavingBar(_a) {
|
|
12
11
|
var _b = _a, {
|
|
13
12
|
status = "unsaved",
|
|
14
13
|
message = "Altera\xE7\xF5es n\xE3o salvas",
|
|
15
14
|
savingMessage = "Salvando\u2026",
|
|
15
|
+
savingLabel = "Salvando\u2026",
|
|
16
16
|
errorMessage = "N\xE3o salvou. Tente de novo.",
|
|
17
17
|
onSave,
|
|
18
18
|
onDiscard,
|
|
@@ -28,6 +28,7 @@ function SavingBar(_a) {
|
|
|
28
28
|
"status",
|
|
29
29
|
"message",
|
|
30
30
|
"savingMessage",
|
|
31
|
+
"savingLabel",
|
|
31
32
|
"errorMessage",
|
|
32
33
|
"onSave",
|
|
33
34
|
"onDiscard",
|
|
@@ -53,7 +54,6 @@ function SavingBar(_a) {
|
|
|
53
54
|
className: ["rds-savingbar", className].filter(Boolean).join(" "),
|
|
54
55
|
children: /* @__PURE__ */ jsxs("div", { className: "rds-savingbar__row", children: [
|
|
55
56
|
/* @__PURE__ */ jsxs("p", { className: ["rds-savingbar__message", details && "rds-savingbar__message--details"].filter(Boolean).join(" "), role: "status", children: [
|
|
56
|
-
saving && /* @__PURE__ */ jsx("span", { className: "rds-savingbar__icon rds-savingbar__loader", "aria-hidden": "true", children: /* @__PURE__ */ jsx(Loader, {}) }),
|
|
57
57
|
error && /* @__PURE__ */ jsx("span", { className: "rds-savingbar__icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx(AlertIcon, {}) }),
|
|
58
58
|
/* @__PURE__ */ jsx("span", { className: "rds-savingbar__text", children: text }),
|
|
59
59
|
details && /* @__PURE__ */ jsxs(
|
|
@@ -76,8 +76,8 @@ function SavingBar(_a) {
|
|
|
76
76
|
)
|
|
77
77
|
] }),
|
|
78
78
|
/* @__PURE__ */ jsxs("div", { className: "rds-savingbar__actions", children: [
|
|
79
|
-
onDiscard && /* @__PURE__ */ jsx(Button, { tone: "neutral", variant: "ghost", disabled: saving, onClick: onDiscard, children: discardLabel }),
|
|
80
|
-
/* @__PURE__ */ jsx(Button, { tone: "action", variant: "fill",
|
|
79
|
+
onDiscard && /* @__PURE__ */ jsx(Button, { className: "rds-savingbar__discard", tone: "neutral", variant: "ghost", disabled: saving, onClick: onDiscard, children: discardLabel }),
|
|
80
|
+
/* @__PURE__ */ jsx(Button, { tone: "action", variant: "fill", loading: saving, loadingLabel: savingLabel, onClick: onSave, children: saving ? savingLabel : error ? retryLabel : saveLabel })
|
|
81
81
|
] })
|
|
82
82
|
] })
|
|
83
83
|
})
|
package/package.json
CHANGED
|
@@ -6783,6 +6783,70 @@ body:has(.rds-modal) {
|
|
|
6783
6783
|
}
|
|
6784
6784
|
}
|
|
6785
6785
|
|
|
6786
|
+
/* components/loading-overlay.css */
|
|
6787
|
+
/* @tokens loading-overlay */
|
|
6788
|
+
/*
|
|
6789
|
+
* LoadingOverlay (Overlays collection, loading-overlay/*): a veil over the whole screen (loading-overlay/scrim,
|
|
6790
|
+
* surface/scrim) in the overlay layer (z/overlay), and a panel in the middle (loading-overlay/background,
|
|
6791
|
+
* surface/card; radius/container, 24 padding, 16 between the Spinner lg and the label, at most 320 wide,
|
|
6792
|
+
* elevation/modal). The label is type/label Medium in loading-overlay/text (text/body), centred. The panel gives the
|
|
6793
|
+
* text its own surface, so it reads over any screen, light, dark or in the brand. It fades in; with reduced motion,
|
|
6794
|
+
* no fade (and the Spinner turns slowly, spinner.css).
|
|
6795
|
+
*/
|
|
6796
|
+
.rds-loading-overlay {
|
|
6797
|
+
position: fixed;
|
|
6798
|
+
inset: 0;
|
|
6799
|
+
z-index: var(--z-overlay);
|
|
6800
|
+
display: flex;
|
|
6801
|
+
align-items: center;
|
|
6802
|
+
justify-content: center;
|
|
6803
|
+
padding: var(--space-16);
|
|
6804
|
+
background: var(--loading-overlay-scrim);
|
|
6805
|
+
animation: rds-loading-overlay-in 150ms ease-out;
|
|
6806
|
+
}
|
|
6807
|
+
|
|
6808
|
+
.rds-loading-overlay__panel {
|
|
6809
|
+
box-sizing: border-box;
|
|
6810
|
+
display: flex;
|
|
6811
|
+
flex-direction: column;
|
|
6812
|
+
align-items: center;
|
|
6813
|
+
gap: var(--space-16);
|
|
6814
|
+
max-width: min(320px, 100%);
|
|
6815
|
+
padding: var(--space-24);
|
|
6816
|
+
border-radius: var(--radius-container);
|
|
6817
|
+
background: var(--loading-overlay-background);
|
|
6818
|
+
box-shadow: var(--elevation-modal);
|
|
6819
|
+
color: var(--loading-overlay-text);
|
|
6820
|
+
font-family: var(--type-font-stack);
|
|
6821
|
+
outline: none;
|
|
6822
|
+
}
|
|
6823
|
+
|
|
6824
|
+
.rds-loading-overlay__label {
|
|
6825
|
+
margin: 0;
|
|
6826
|
+
font-size: var(--type-label-size);
|
|
6827
|
+
font-weight: 500;
|
|
6828
|
+
line-height: var(--type-label-line);
|
|
6829
|
+
text-align: center;
|
|
6830
|
+
}
|
|
6831
|
+
|
|
6832
|
+
@keyframes rds-loading-overlay-in {
|
|
6833
|
+
from {
|
|
6834
|
+
opacity: 0;
|
|
6835
|
+
}
|
|
6836
|
+
}
|
|
6837
|
+
|
|
6838
|
+
@media (prefers-reduced-motion: reduce) {
|
|
6839
|
+
.rds-loading-overlay {
|
|
6840
|
+
animation: none;
|
|
6841
|
+
}
|
|
6842
|
+
}
|
|
6843
|
+
|
|
6844
|
+
@media (forced-colors: active) {
|
|
6845
|
+
.rds-loading-overlay__panel {
|
|
6846
|
+
border: var(--border-width) solid CanvasText;
|
|
6847
|
+
}
|
|
6848
|
+
}
|
|
6849
|
+
|
|
6786
6850
|
/* components/marker.css */
|
|
6787
6851
|
/* @tokens marker */
|
|
6788
6852
|
/*
|
|
@@ -8467,10 +8531,13 @@ input:focus-visible + .rds-radio__circle {
|
|
|
8467
8531
|
* The bar redeclares the Button tokens those two read: the Salvar fill is savingbar/button/fill/background with
|
|
8468
8532
|
* savingbar/button/fill/label, its hover the fill at 85% over the bar (active 70%); the Descartar label is
|
|
8469
8533
|
* savingbar/button/ghost/label, its hover the label colour at 15% (active 25%); the focus ring is savingbar/focus/ring;
|
|
8470
|
-
* disabled (saving) is
|
|
8534
|
+
* disabled (Descartar while saving) is the Button at 40% over the bar, as the Figma layer opacity. While saving, Salvar
|
|
8535
|
+
* is in loading (its loader in the label colour): the only indicator, none in the message.
|
|
8471
8536
|
* Two arrangements, by the screen width, as the Figma viewport mode (layout/compact below lg 1024): expanded from 1024,
|
|
8472
|
-
* the message grows (at least 160) beside
|
|
8473
|
-
*
|
|
8537
|
+
* 12 24 padding (68 tall), the message grows (at least 160) beside Descartar and Salvar; compact below it, one row,
|
|
8538
|
+
* 10 24 padding (64 = 10 + 44 + 10) plus the safe area at the bottom, the message (flex 1, at most 2 lines) on the
|
|
8539
|
+
* left and only the main button on the right: Descartar is not shown (it lives in the details Drawer's footer or in
|
|
8540
|
+
* the confirmation when leaving).
|
|
8474
8541
|
* Details (showDetails, onDetails in code): in compact, the unsaved message becomes a text button with chevron-up 20 at
|
|
8475
8542
|
* the right (12 apart) that opens the Drawer with what is missing; hover underlines, focus draws the ring
|
|
8476
8543
|
* savingbar/focus/ring (focus/ring-width, radius/focus) 4 around the message box, inside stroke, as the Figma
|
|
@@ -8543,22 +8610,6 @@ input:focus-visible + .rds-radio__circle {
|
|
|
8543
8610
|
height: 100%;
|
|
8544
8611
|
}
|
|
8545
8612
|
|
|
8546
|
-
.rds-savingbar__loader > svg {
|
|
8547
|
-
animation: rds-savingbar-turn 1s linear infinite;
|
|
8548
|
-
}
|
|
8549
|
-
|
|
8550
|
-
@keyframes rds-savingbar-turn {
|
|
8551
|
-
to {
|
|
8552
|
-
transform: rotate(360deg);
|
|
8553
|
-
}
|
|
8554
|
-
}
|
|
8555
|
-
|
|
8556
|
-
@media (prefers-reduced-motion: reduce) {
|
|
8557
|
-
.rds-savingbar__loader > svg {
|
|
8558
|
-
animation-duration: 3s;
|
|
8559
|
-
}
|
|
8560
|
-
}
|
|
8561
|
-
|
|
8562
8613
|
.rds-savingbar__actions {
|
|
8563
8614
|
display: flex;
|
|
8564
8615
|
flex: none;
|
|
@@ -8605,19 +8656,18 @@ input:focus-visible + .rds-radio__circle {
|
|
|
8605
8656
|
}
|
|
8606
8657
|
|
|
8607
8658
|
@media (max-width: 1023px) {
|
|
8608
|
-
.rds-
|
|
8609
|
-
|
|
8610
|
-
|
|
8659
|
+
.rds-savingbar {
|
|
8660
|
+
padding-block: 10px;
|
|
8661
|
+
padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px));
|
|
8611
8662
|
}
|
|
8612
8663
|
|
|
8613
8664
|
.rds-savingbar__message {
|
|
8614
|
-
flex:
|
|
8665
|
+
flex: 1 1 0;
|
|
8615
8666
|
min-width: 0;
|
|
8616
8667
|
}
|
|
8617
8668
|
|
|
8618
|
-
.rds-
|
|
8619
|
-
|
|
8620
|
-
min-width: 0;
|
|
8669
|
+
.rds-savingbar .rds-savingbar__discard {
|
|
8670
|
+
display: none;
|
|
8621
8671
|
}
|
|
8622
8672
|
|
|
8623
8673
|
.rds-savingbar__message--details > .rds-savingbar__text {
|
|
@@ -908,11 +908,11 @@
|
|
|
908
908
|
--progress-fill: var(--chart-series-1);
|
|
909
909
|
--progress-label: var(--text-body);
|
|
910
910
|
--progress-value: var(--text-muted);
|
|
911
|
-
--spinner-indicator: var(--colors-primary-
|
|
911
|
+
--spinner-indicator: var(--colors-primary-dark);
|
|
912
912
|
--spinner-track: var(--surface-tint-strong);
|
|
913
913
|
--spinner-label: var(--text-muted);
|
|
914
|
-
--spinner-inverse-indicator: var(--text-on-primary
|
|
915
|
-
--spinner-inverse-label: var(--text-on-primary
|
|
914
|
+
--spinner-inverse-indicator: var(--text-on-primary);
|
|
915
|
+
--spinner-inverse-label: var(--text-on-primary);
|
|
916
916
|
--rating-empty: var(--border-strong);
|
|
917
917
|
--rating-label: var(--text-muted);
|
|
918
918
|
--rating-star: var(--colors-state-warning);
|
|
@@ -1007,5 +1007,8 @@
|
|
|
1007
1007
|
--image-crop-dialog-selection: var(--text-on-cover);
|
|
1008
1008
|
--image-crop-dialog-handle: var(--text-on-cover);
|
|
1009
1009
|
--image-crop-dialog-stage-background: var(--surface-muted);
|
|
1010
|
+
--loading-overlay-scrim: var(--surface-scrim);
|
|
1011
|
+
--loading-overlay-background: var(--surface-card);
|
|
1012
|
+
--loading-overlay-text: var(--text-body);
|
|
1010
1013
|
}
|
|
1011
1014
|
}
|