component.test.ts 4.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import { expect, test } from "bun:test"
  2. import { createSignal } from "solid-js"
  3. import { RGBA } from "@opentui/core"
  4. import { DEFAULT_THEME, resolveTheme, selectTheme, type ContextName } from "@opencode-ai/theme/tui"
  5. import { createComponentTheme } from "../../../src/theme/component"
  6. test("provides reactive properties, states, contexts, and color operations", () => {
  7. const [resolved, setResolved] = createSignal(resolveTheme(selectTheme(DEFAULT_THEME, "light")))
  8. const [mode, setMode] = createSignal<"light" | "dark">("light")
  9. const theme = createComponentTheme(resolved, mode)
  10. const [context, setContext] = createSignal<ContextName>()
  11. const current = () => {
  12. const name = context()
  13. return name ? theme.contextual[name] : theme
  14. }
  15. expect(theme.text.default).toBe(resolved().text.default)
  16. expect(theme.hue.accent[500]).toBe(resolved().hue.accent[500])
  17. expect(theme.hue.interactive[500]).toBe(resolved().hue.interactive[500])
  18. expect(theme.hue.gray[200]).toBe(resolved().hue.gray[200])
  19. expect(theme.categorical.map((scale) => scale[500])).toEqual(resolved().categorical.map((scale) => scale[500]))
  20. expect(theme.increase(theme.background.surface.offset, 1)).toBe(resolved().hue.neutral[400])
  21. expect(theme.raise(theme.background.surface.offset)).toBe(resolved().hue.neutral[400])
  22. expect(theme.decrease(theme.hue.red[300], 2)).toBe(resolved().hue.red[100])
  23. expect(theme.increase(theme.hue.red[900], 3)).toBe(resolved().hue.red[900])
  24. expect(theme.decrease(theme.hue.red[100], 3)).toBe(resolved().hue.red[100])
  25. expect(theme.source(theme.background.surface.offset)).toEqual({ hue: "neutral", step: 300 })
  26. const equivalent = RGBA.fromInts(...resolved().hue.green[500].toInts())
  27. expect(theme.source(equivalent)).toBeUndefined()
  28. expect(theme.increase(equivalent, 1)).toBe(equivalent)
  29. const unmatched = RGBA.fromInts(1, 2, 3)
  30. expect(theme.increase(unmatched, 1)).toBe(unmatched)
  31. expect(theme.text.subdued).toBe(resolved().text.subdued)
  32. expect(theme.text.action.primary.default).toBe(resolved().text.action.primary.default)
  33. expect(theme.text.action.primary.hovered).toBe(resolved().text.action.primary.hovered)
  34. expect(theme.text.action.primary.pressed).toBe(resolved().text.action.primary.pressed)
  35. expect(theme.text.action.primary.selected).toBe(resolved().text.action.primary.selected)
  36. expect(theme.background.action.primary.selected).toBe(resolved().background.action.primary.selected)
  37. expect(theme.background.action.primary.hovered).toBe(resolved().background.action.primary.hovered)
  38. expect(theme.background.action.primary.focused).toBe(resolved().background.action.primary.focused)
  39. expect(theme.background.action.primary.pressed).toBe(resolved().background.action.primary.pressed)
  40. expect(theme.background.action.primary.disabled).toBe(resolved().background.action.primary.disabled)
  41. expect(theme.background.action.primary.default).toBe(resolved().background.action.primary.default)
  42. expect(theme.background.action.destructive.disabled).toBe(resolved().background.action.destructive.disabled)
  43. expect(theme.background.formfield.hovered).toBe(resolved().background.formfield.hovered)
  44. expect(theme.background.formfield.selected).toBe(resolved().background.formfield.selected)
  45. expect(theme.background.formfield.focused).toBe(resolved().background.formfield.focused)
  46. expect(theme.background.formfield.disabled).toBe(resolved().background.formfield.disabled)
  47. expect(theme.background.surface.offset).toBe(resolved().background.surface.offset)
  48. expect(theme.background.surface.overlay).toBe(resolved().background.surface.overlay)
  49. expect(theme.scrollbar.default).toBe(resolved().scrollbar.default)
  50. expect(theme.diff.text.added).toBe(resolved().diff.text.added)
  51. setContext("elevated")
  52. expect("contexts" in current()).toBeFalse()
  53. expect(current().categorical.map((scale) => scale[500])).toEqual(resolved().categorical.map((scale) => scale[500]))
  54. expect(current().text.default).toBe(resolved().contextual.elevated.text.default)
  55. expect(current().background.action.primary.focused).toBe(
  56. resolved().contextual.elevated.background.action.primary.focused,
  57. )
  58. expect(current().background.action.primary.hovered).toBe(resolved().background.surface.overlay)
  59. expect(current().background.formfield.selected).toBe(
  60. resolved().contextual.elevated.background.formfield.selected,
  61. )
  62. setResolved(resolveTheme(selectTheme(DEFAULT_THEME, "dark")))
  63. setMode("dark")
  64. expect(current().text.default).toBe(resolved().contextual.elevated.text.default)
  65. expect(current().decrease(current().background.surface.offset, 1)).toBe(resolved().hue.neutral[600])
  66. expect(current().raise(current().background.surface.offset)).toBe(resolved().hue.neutral[600])
  67. })