Add ghost button variants

Nate Butler created

Change summary

styles/src/component/button.ts      |  6 ++++++
styles/src/component/icon_button.ts | 12 ++++++++----
styles/src/component/text_button.ts |  9 ++++++---
3 files changed, 20 insertions(+), 7 deletions(-)

Detailed changes

styles/src/component/button.ts 🔗

@@ -0,0 +1,6 @@
+export const ButtonVariant = {
+    Default: 'default',
+    Ghost: 'ghost'
+} as const
+
+export type Variant = typeof ButtonVariant[keyof typeof ButtonVariant]

styles/src/component/icon_button.ts 🔗

@@ -1,6 +1,7 @@
 import { interactive, toggleable } from "../element"
 import { background, foreground } from "../style_tree/components"
 import { useTheme, Theme } from "../theme"
+import { ButtonVariant, Variant } from "./button"
 
 export type Margin = {
     top: number
@@ -16,17 +17,20 @@ interface IconButtonOptions {
     | Theme["highest"]
     color?: keyof Theme["lowest"]
     margin?: Partial<Margin>
+    variant?: Variant
 }
 
 type ToggleableIconButtonOptions = IconButtonOptions & {
     active_color?: keyof Theme["lowest"]
 }
 
-export function icon_button({ color, margin, layer }: IconButtonOptions) {
+export function icon_button({ color, margin, layer, variant = ButtonVariant.Default }: IconButtonOptions) {
     const theme = useTheme()
 
     if (!color) color = "base"
 
+    const background_color = variant === ButtonVariant.Ghost ? null : background(layer ?? theme.lowest, color)
+
     const m = {
         top: margin?.top ?? 0,
         bottom: margin?.bottom ?? 0,
@@ -51,7 +55,7 @@ export function icon_button({ color, margin, layer }: IconButtonOptions) {
         },
         state: {
             default: {
-                background: background(layer ?? theme.lowest, color),
+                background: background_color,
                 color: foreground(layer ?? theme.lowest, color),
             },
             hovered: {
@@ -68,13 +72,13 @@ export function icon_button({ color, margin, layer }: IconButtonOptions) {
 
 export function toggleable_icon_button(
     theme: Theme,
-    { color, active_color, margin }: ToggleableIconButtonOptions
+    { color, active_color, margin, variant }: ToggleableIconButtonOptions
 ) {
     if (!color) color = "base"
 
     return toggleable({
         state: {
-            inactive: icon_button({ color, margin }),
+            inactive: icon_button({ color, margin, variant }),
             active: icon_button({
                 color: active_color ? active_color : color,
                 margin,

styles/src/component/text_button.ts 🔗

@@ -6,6 +6,7 @@ import {
     text,
 } from "../style_tree/components"
 import { useTheme, Theme } from "../theme"
+import { ButtonVariant, Variant } from "./button"
 import { Margin } from "./icon_button"
 
 interface TextButtonOptions {
@@ -13,7 +14,7 @@ interface TextButtonOptions {
     | Theme["lowest"]
     | Theme["middle"]
     | Theme["highest"]
-    variant?: "default" | "ghost"
+    variant?: Variant
     color?: keyof Theme["lowest"]
     margin?: Partial<Margin>
     text_properties?: TextProperties
@@ -24,7 +25,7 @@ type ToggleableTextButtonOptions = TextButtonOptions & {
 }
 
 export function text_button({
-    variant = "default",
+    variant = ButtonVariant.Default,
     color,
     layer,
     margin,
@@ -33,6 +34,8 @@ export function text_button({
     const theme = useTheme()
     if (!color) color = "base"
 
+    const background_color = variant === ButtonVariant.Ghost ? null : background(layer ?? theme.lowest, color)
+
     const text_options: TextProperties = {
         size: "xs",
         weight: "normal",
@@ -61,7 +64,7 @@ export function text_button({
         },
         state: {
             default: {
-                background: variant !== "ghost" ? background(layer ?? theme.lowest, color) : null,
+                background: background_color,
                 color: foreground(layer ?? theme.lowest, color),
             },
             hovered: {