refactor(app): migrate small styles to tailwind
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { LoadingIndicator } from "../loading-indicator";
|
||||
|
||||
describe("core Tailwind components", () => {
|
||||
it("renders LoadingIndicator with accessible status and dynamic sizing", () => {
|
||||
const html = renderToStaticMarkup(
|
||||
<LoadingIndicator size={24} strokeWidth={2} color="#f00" label="Loading now" />,
|
||||
);
|
||||
|
||||
expect(html).toContain('role="status"');
|
||||
expect(html).toContain('aria-label="Loading"');
|
||||
expect(html).toContain("animate-spin");
|
||||
expect(html).toContain("width:24px");
|
||||
expect(html).toContain("height:24px");
|
||||
expect(html).toContain("border-width:2px");
|
||||
expect(html).toContain("border-color:#f00 transparent transparent transparent");
|
||||
expect(html).toContain("Loading now");
|
||||
});
|
||||
});
|
||||
@@ -1,26 +0,0 @@
|
||||
.wrapper {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: var(--spacing-sm);
|
||||
}
|
||||
|
||||
.spinner {
|
||||
display: inline-block;
|
||||
border-style: solid;
|
||||
border-color: var(--color-text-secondary) transparent transparent
|
||||
transparent;
|
||||
border-radius: 50%;
|
||||
animation: spin 0.8s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
color: var(--color-text-secondary);
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
@@ -7,10 +7,10 @@
|
||||
* 行为对齐 Flutter `CircularProgressIndicator`:
|
||||
* - `size`:圆圈直径(默认 32)
|
||||
* - `strokeWidth`:环宽(默认 3)
|
||||
* - `color`:环颜色(默认 `--color-accent`)
|
||||
* - `color`:环颜色(默认 `--color-text-secondary`)
|
||||
* - `label`:可选的可视标签(环形下方文本)
|
||||
*/
|
||||
import styles from "./loading-indicator.module.css";
|
||||
import type { CSSProperties } from "react";
|
||||
|
||||
export interface LoadingIndicatorProps {
|
||||
size?: number;
|
||||
@@ -25,16 +25,28 @@ export function LoadingIndicator({
|
||||
color,
|
||||
label,
|
||||
}: LoadingIndicatorProps) {
|
||||
const style: React.CSSProperties = {
|
||||
const spinnerColor = color ?? "var(--color-text-secondary)";
|
||||
const style: CSSProperties = {
|
||||
width: size,
|
||||
height: size,
|
||||
borderWidth: strokeWidth,
|
||||
...(color ? { borderTopColor: color } : {}),
|
||||
borderColor: `${spinnerColor} transparent transparent transparent`,
|
||||
};
|
||||
return (
|
||||
<div className={styles.wrapper} role="status" aria-label="Loading">
|
||||
<div className={styles.spinner} style={style} />
|
||||
{label ? <span className={styles.label}>{label}</span> : null}
|
||||
<div
|
||||
className="inline-flex flex-col items-center gap-sm"
|
||||
role="status"
|
||||
aria-label="Loading"
|
||||
>
|
||||
<div
|
||||
className="inline-block animate-spin rounded-full border-solid"
|
||||
style={style}
|
||||
/>
|
||||
{label ? (
|
||||
<span className="text-[var(--font-size-sm)] text-text-secondary">
|
||||
{label}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user