Update toggle, add tests

Nate Butler created

Change summary

styles/src/element/index.ts                 |  3 
styles/src/element/toggle.test.ts           | 52 +++++++++++++++++++++++
styles/src/element/toggle.ts                |  4 
styles/src/styleTree/commandPalette.ts      |  3 
styles/src/styleTree/contactList.ts         |  3 
styles/src/styleTree/contextMenu.ts         |  3 
styles/src/styleTree/editor.ts              |  3 
styles/src/styleTree/picker.ts              |  3 
styles/src/styleTree/projectPanel.ts        |  3 
styles/src/styleTree/search.ts              |  3 
styles/src/styleTree/statusBar.ts           |  3 
styles/src/styleTree/tabBar.ts              |  3 
styles/src/styleTree/toolbarDropdownMenu.ts |  3 
styles/src/styleTree/workspace.ts           |  2 
14 files changed, 67 insertions(+), 24 deletions(-)

Detailed changes

styles/src/element/index.ts 🔗

@@ -1,3 +1,4 @@
 import { interactive } from "./interactive"
+import { toggleable } from "./toggle"
 
-export { interactive }
+export { interactive, toggleable }

styles/src/element/toggle.test.ts 🔗

@@ -0,0 +1,52 @@
+import {
+    NO_ACTIVE_ERROR,
+    NO_INACTIVE_OR_BASE_ERROR,
+    toggleable,
+} from "./toggle"
+import { describe, it, expect } from "vitest"
+
+describe("toggleable", () => {
+    it("creates a Toggleable<Element> with base properties and states", () => {
+        const result = toggleable({
+            base: { background: "#000000", color: "#CCCCCC" },
+            state: {
+                active: { color: "#FFFFFF" },
+            },
+        })
+
+        expect(result).toEqual({
+            inactive: { background: "#000000", color: "#CCCCCC" },
+            active: { background: "#000000", color: "#FFFFFF" },
+        })
+    })
+
+    it("creates a Toggleable<Element> with no base properties", () => {
+        const result = toggleable({
+            state: {
+                inactive: { background: "#000000", color: "#CCCCCC" },
+                active: { background: "#000000", color: "#FFFFFF" },
+            },
+        })
+
+        expect(result).toEqual({
+            inactive: { background: "#000000", color: "#CCCCCC" },
+            active: { background: "#000000", color: "#FFFFFF" },
+        })
+    })
+
+    it("throws error when both inactive and base are missing", () => {
+        const state = {
+            active: { background: "#000000", color: "#FFFFFF" },
+        }
+
+        expect(() => toggleable({ state })).toThrow(NO_INACTIVE_OR_BASE_ERROR)
+    })
+
+    it("throws error when no active state is present", () => {
+        const state = {
+            inactive: { background: "#000000", color: "#CCCCCC" },
+        }
+
+        expect(() => toggleable({ state })).toThrow(NO_ACTIVE_ERROR)
+    })
+})

styles/src/element/toggle.ts 🔗

@@ -4,9 +4,9 @@ type ToggleState = "inactive" | "active"
 
 type Toggleable<T> = Record<ToggleState, T>
 
-const NO_INACTIVE_OR_BASE_ERROR =
+export const NO_INACTIVE_OR_BASE_ERROR =
     "A toggleable object must have an inactive state, or a base property."
-const NO_ACTIVE_ERROR = "A toggleable object must have an active state."
+export const NO_ACTIVE_ERROR = "A toggleable object must have an active state."
 
 interface ToggleableProps<T> {
     base?: T

styles/src/styleTree/commandPalette.ts 🔗

@@ -1,8 +1,7 @@
 import { ColorScheme } from "../theme/colorScheme"
 import { withOpacity } from "../theme/color"
 import { text, background } from "./components"
-import { toggleable } from "./toggle"
-import { interactive } from "../element"
+import { interactive, toggleable } from "../element"
 
 export default function commandPalette(colorScheme: ColorScheme) {
     let layer = colorScheme.highest

styles/src/styleTree/contactList.ts 🔗

@@ -1,7 +1,6 @@
 import { ColorScheme } from "../theme/colorScheme"
 import { background, border, borderColor, foreground, text } from "./components"
-import { toggleable } from "./toggle"
-import { interactive } from "../element"
+import { interactive, toggleable } from "../element"
 export default function contactsPanel(colorScheme: ColorScheme) {
     const nameMargin = 8
     const sidePadding = 12

styles/src/styleTree/contextMenu.ts 🔗

@@ -1,7 +1,6 @@
 import { ColorScheme } from "../theme/colorScheme"
 import { background, border, borderColor, text } from "./components"
-import { interactive } from "../element"
-import { toggleable } from "./toggle"
+import { interactive, toggleable } from "../element"
 
 export default function contextMenu(colorScheme: ColorScheme) {
     let layer = colorScheme.middle

styles/src/styleTree/editor.ts 🔗

@@ -4,8 +4,7 @@ import { background, border, borderColor, foreground, text } from "./components"
 import hoverPopover from "./hoverPopover"
 
 import { buildSyntax } from "../theme/syntax"
-import { interactive } from "../element"
-import { toggleable } from "./toggle"
+import { interactive, toggleable } from "../element"
 
 export default function editor(colorScheme: ColorScheme) {
     const { isLight } = colorScheme

styles/src/styleTree/picker.ts 🔗

@@ -1,8 +1,7 @@
 import { ColorScheme } from "../theme/colorScheme"
 import { withOpacity } from "../theme/color"
 import { background, border, text } from "./components"
-import { toggleable } from "./toggle"
-import { interactive } from "../element"
+import { interactive, toggleable } from "../element"
 
 export default function picker(colorScheme: ColorScheme): any {
     let layer = colorScheme.lowest

styles/src/styleTree/projectPanel.ts 🔗

@@ -1,8 +1,7 @@
 import { ColorScheme } from "../theme/colorScheme"
 import { withOpacity } from "../theme/color"
 import { background, border, foreground, text } from "./components"
-import { interactive } from "../element"
-import { toggleable } from "./toggle"
+import { interactive, toggleable } from "../element"
 export default function projectPanel(colorScheme: ColorScheme) {
     const { isLight } = colorScheme
 

styles/src/styleTree/search.ts 🔗

@@ -1,8 +1,7 @@
 import { ColorScheme } from "../theme/colorScheme"
 import { withOpacity } from "../theme/color"
 import { background, border, foreground, text } from "./components"
-import { interactive } from "../element"
-import { toggleable } from "./toggle"
+import { interactive, toggleable } from "../element"
 
 export default function search(colorScheme: ColorScheme) {
     let layer = colorScheme.highest

styles/src/styleTree/statusBar.ts 🔗

@@ -1,7 +1,6 @@
 import { ColorScheme } from "../theme/colorScheme"
 import { background, border, foreground, text } from "./components"
-import { interactive } from "../element"
-import { toggleable } from "./toggle"
+import { interactive, toggleable } from "../element"
 export default function statusBar(colorScheme: ColorScheme) {
     let layer = colorScheme.lowest
 

styles/src/styleTree/tabBar.ts 🔗

@@ -1,8 +1,7 @@
 import { ColorScheme } from "../theme/colorScheme"
 import { withOpacity } from "../theme/color"
 import { text, border, background, foreground } from "./components"
-import { toggleable } from "./toggle"
-import { interactive } from "../element"
+import { interactive, toggleable } from "../element"
 
 export default function tabBar(colorScheme: ColorScheme) {
     const height = 32

styles/src/styleTree/toolbarDropdownMenu.ts 🔗

@@ -1,7 +1,6 @@
 import { ColorScheme } from "../theme/colorScheme"
 import { background, border, text } from "./components"
-import { interactive } from "../element"
-import { toggleable } from "./toggle"
+import { interactive, toggleable } from "../element"
 export default function dropdownMenu(colorScheme: ColorScheme) {
     let layer = colorScheme.middle
 

styles/src/styleTree/workspace.ts 🔗

@@ -1,6 +1,6 @@
 import { ColorScheme } from "../theme/colorScheme"
 import { withOpacity } from "../theme/color"
-import { toggleable } from "./toggle"
+import { toggleable } from "../element"
 import {
     background,
     border,