All files / src/skeletonize appearance.ts

100% Statements 10/10
95% Branches 19/20
100% Functions 1/1
100% Lines 10/10

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46                                    24x 24x                   2643x   2643x         2643x 2643x   2643x 2643x 2643x   2643x    
import type { SkeletonAnimationName } from "../components/Skeleton/types";
import { generateAutoHighlight } from "../components/Skeleton/utils/color";
 
export interface SkeletonAppearanceInput {
  color?: string;
  highlight?: string;
  animation?: SkeletonAnimationName;
  speed?: number;
}
 
export interface SkeletonAppearance {
  base: string;
  highlight: string;
  animation: "shimmer" | "pulse" | "none";
  /** CSS time, e.g. "1500ms"; "0ms" when not animated. */
  duration: string;
}
 
export const DEFAULT_SKELETON_BASE = "rgba(148, 163, 184, 0.22)";
const BASE_DURATION_MS = 1500;
 
/**
 * Colors and animation shared by <Skeleton> and v-skeleton, so both always
 * look the same. Each value resolves as: explicit prop > config > default.
 */
export function resolveSkeletonAppearance(
  props: SkeletonAppearanceInput,
  config: SkeletonAppearanceInput = {}
): SkeletonAppearance {
  const base = props.color ?? config.color ?? DEFAULT_SKELETON_BASE;
  const highlight =
    props.highlight ??
    config.highlight ??
    generateAutoHighlight(base, { lightThreshold: 0.8, lightenBy: 0.5, darkenBy: 0.22, alphaBoost: 0.06 }) ??
    "rgba(255, 255, 255, 0.35)";
 
  const raw = props.animation ?? config.animation ?? "shimmer";
  const animation = raw === "wave" ? "shimmer" : raw;
 
  const speed = props.speed ?? config.speed ?? 1;
  const s = speed > 0 ? speed : 1;
  const duration = animation === "none" ? "0ms" : `${Math.round(BASE_DURATION_MS / s)}ms`;
 
  return { base, highlight, animation, duration };
}