1import { interactive, toggleable } from "../element"
2import {
3 Border,
4 TextProperties,
5 background,
6 foreground,
7 text,
8} from "../style_tree/components"
9import { useTheme, Theme } from "../theme"
10import { Button } from "./button"
11import { Margin } from "./icon_button"
12
13interface TextButtonOptions {
14 layer?: Theme["lowest"] | Theme["middle"] | Theme["highest"]
15 variant?: Button.Variant
16 color?: keyof Theme["lowest"]
17 margin?: Partial<Margin>
18 disabled?: boolean
19 text_properties?: TextProperties
20 border?: Border
21}
22
23type ToggleableTextButtonOptions = TextButtonOptions & {
24 active_color?: keyof Theme["lowest"]
25}
26
27export function text_button({
28 variant = Button.variant.Default,
29 color,
30 layer,
31 margin,
32 disabled,
33 text_properties,
34 border,
35}: TextButtonOptions = {}) {
36 const theme = useTheme()
37 if (!color) color = "base"
38
39 const background_color =
40 variant === Button.variant.Ghost
41 ? null
42 : background(layer ?? theme.lowest, color)
43
44 const text_options: TextProperties = {
45 size: "xs",
46 weight: "normal",
47 ...text_properties,
48 }
49
50 const m = {
51 top: margin?.top ?? 0,
52 bottom: margin?.bottom ?? 0,
53 left: margin?.left ?? 0,
54 right: margin?.right ?? 0,
55 }
56
57 return interactive({
58 base: {
59 corner_radius: 6,
60 padding: {
61 top: 1,
62 bottom: 1,
63 left: 6,
64 right: 6,
65 },
66 margin: m,
67 button_height: 22,
68 ...text(layer ?? theme.lowest, "sans", color, text_options),
69 },
70 state: {
71 default: {
72 border,
73 background: background_color,
74 color: disabled
75 ? foreground(layer ?? theme.lowest, "disabled")
76 : foreground(layer ?? theme.lowest, color),
77 },
78 hovered: disabled
79 ? {}
80 : {
81 border,
82 background: background(
83 layer ?? theme.lowest,
84 color,
85 "hovered"
86 ),
87 color: foreground(
88 layer ?? theme.lowest,
89 color,
90 "hovered"
91 ),
92 },
93 clicked: disabled
94 ? {}
95 : {
96 border,
97 background: background(
98 layer ?? theme.lowest,
99 color,
100 "pressed"
101 ),
102 color: foreground(
103 layer ?? theme.lowest,
104 color,
105 "pressed"
106 ),
107 },
108 },
109 })
110}
111
112export function toggleable_text_button(
113 theme: Theme,
114 { variant, color, active_color, margin }: ToggleableTextButtonOptions = {}
115) {
116 if (!color) color = "base"
117
118 return toggleable({
119 state: {
120 inactive: text_button({ variant, color, margin }),
121 active: text_button({
122 variant,
123 color: active_color ? active_color : color,
124 margin,
125 layer: theme.middle,
126 }),
127 },
128 })
129}