(themeInput: unknown)
| 453 | }; |
| 454 | |
| 455 | const resolveTheme = (themeInput: unknown): ThemeConfig => { |
| 456 | const base = getTheme('dark'); |
| 457 | |
| 458 | if (typeof themeInput === 'string') { |
| 459 | const name = themeInput.trim().toLowerCase(); |
| 460 | return name === 'light' ? getTheme('light') : getTheme('dark'); |
| 461 | } |
| 462 | |
| 463 | if (themeInput === null || typeof themeInput !== 'object' || Array.isArray(themeInput)) { |
| 464 | return base; |
| 465 | } |
| 466 | |
| 467 | const input = themeInput as Partial<Record<keyof ThemeConfig, unknown>>; |
| 468 | const takeString = (key: keyof ThemeConfig): string | undefined => { |
| 469 | const v = input[key]; |
| 470 | if (typeof v !== 'string') return undefined; |
| 471 | const trimmed = v.trim(); |
| 472 | return trimmed.length > 0 ? trimmed : undefined; |
| 473 | }; |
| 474 | |
| 475 | const fontSizeRaw = input.fontSize; |
| 476 | const fontSize = |
| 477 | typeof fontSizeRaw === 'number' && Number.isFinite(fontSizeRaw) ? fontSizeRaw : undefined; |
| 478 | |
| 479 | const colorPaletteCandidate = sanitizePalette(input.colorPalette); |
| 480 | |
| 481 | return { |
| 482 | backgroundColor: takeString('backgroundColor') ?? base.backgroundColor, |
| 483 | textColor: takeString('textColor') ?? base.textColor, |
| 484 | axisLineColor: takeString('axisLineColor') ?? base.axisLineColor, |
| 485 | axisTickColor: takeString('axisTickColor') ?? base.axisTickColor, |
| 486 | gridLineColor: takeString('gridLineColor') ?? base.gridLineColor, |
| 487 | colorPalette: colorPaletteCandidate.length > 0 ? colorPaletteCandidate : Array.from(base.colorPalette), |
| 488 | fontFamily: takeString('fontFamily') ?? base.fontFamily, |
| 489 | fontSize: fontSize ?? base.fontSize, |
| 490 | }; |
| 491 | }; |
| 492 | |
| 493 | const normalizeOptionalColor = (color: unknown): string | undefined => { |
| 494 | if (typeof color !== 'string') return undefined; |
no test coverage detected