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