feat(ui): add activity indicator governance

This commit is contained in:
Codex
2026-08-13 11:38:26 +03:00
parent d6c62da470
commit bbb50e06b4
9 changed files with 276 additions and 1 deletions
+25
View File
@@ -211,6 +211,30 @@
transform: scale(var(--nodedc-icon-glyph-scale));
}
.nodedc-activity-indicator {
display: inline-block;
width: 1.125rem;
height: 1.125rem;
flex: 0 0 auto;
box-sizing: border-box;
border: 2px solid currentColor;
border-inline-end-color: transparent;
border-radius: var(--nodedc-radius-circle);
color: inherit;
opacity: 0.78;
animation: nodedc-activity-indicator-spin 780ms linear infinite;
}
.nodedc-activity-indicator[data-size="compact"] {
width: 0.875rem;
height: 0.875rem;
border-width: 1.5px;
}
@keyframes nodedc-activity-indicator-spin {
to { transform: rotate(360deg); }
}
.nodedc-icon-button {
display: inline-grid;
width: var(--nodedc-icon-button-size);
@@ -3585,6 +3609,7 @@ textarea.nodedc-field__control {
}
@media (prefers-reduced-motion: reduce) {
.nodedc-activity-indicator,
.nodedc-dropdown-surface,
.nodedc-overlay,
.nodedc-window,
@@ -0,0 +1,32 @@
import type { HTMLAttributes } from "react";
import { cn } from "./cn.js";
export type ActivityIndicatorSize = "default" | "compact";
export interface ActivityIndicatorProps extends Omit<
HTMLAttributes<HTMLSpanElement>,
"aria-hidden" | "aria-label" | "children" | "role"
> {
size?: ActivityIndicatorSize;
label?: string;
}
export function ActivityIndicator({
size = "default",
label,
className,
...props
}: ActivityIndicatorProps) {
const accessibleLabel = label?.trim() || undefined;
return (
<span
{...props}
className={cn("nodedc-activity-indicator", className)}
data-size={size === "default" ? undefined : size}
role={accessibleLabel ? "status" : undefined}
aria-label={accessibleLabel}
aria-hidden={accessibleLabel ? undefined : "true"}
/>
);
}
+1
View File
@@ -1,4 +1,5 @@
export * from "./AppHeader.js";
export * from "./ActivityIndicator.js";
export * from "./AdminNavigationPanel.js";
export * from "./ApplicationShell.js";
export * from "./ApplicationSidePanel.js";