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 { Margin } from "./icon_button"
10
11interface TextButtonOptions {
12 layer?:
13 | Theme["lowest"]
14 | Theme["middle"]
15 | Theme["highest"]
16 variant?: "default" | "ghost"
17 color?: keyof Theme["lowest"]
18 margin?: Partial<Margin>
19 text_properties?: TextProperties
20}
21
22type ToggleableTextButtonOptions = TextButtonOptions & {
23 active_color?: keyof Theme["lowest"]
24}
25
26export function text_button({
27 variant = "default",
28 color,
29 layer,
30 margin,
31 text_properties,
32}: TextButtonOptions) {
33 const theme = useTheme()
34 if (!color) color = "base"
35
36 const text_options: TextProperties = {
37 size: "xs",
38 weight: "normal",
39 ...text_properties,
40 }
41
42 const m = {
43 top: margin?.top ?? 0,
44 bottom: margin?.bottom ?? 0,
45 left: margin?.left ?? 0,
46 right: margin?.right ?? 0,
47 }
48
49 return interactive({
50 base: {
51 corner_radius: 6,
52 padding: {
53 top: 1,
54 bottom: 1,
55 left: 6,
56 right: 6,
57 },
58 margin: m,
59 button_height: 22,
60 ...text(layer ?? theme.lowest, "sans", color, text_options),
61 },
62 state: {
63 default: {
64 background: variant !== "ghost" ? background(layer ?? theme.lowest, color) : null,
65 color: foreground(layer ?? theme.lowest, color),
66 },
67 hovered: {
68 background: background(layer ?? theme.lowest, color, "hovered"),
69 color: foreground(layer ?? theme.lowest, color, "hovered"),
70 },
71 clicked: {
72 background: background(layer ?? theme.lowest, color, "pressed"),
73 color: foreground(layer ?? theme.lowest, color, "pressed"),
74 },
75 },
76 })
77}
78
79export function toggleable_text_button(
80 theme: Theme,
81 { variant, color, active_color, margin }: ToggleableTextButtonOptions
82) {
83 if (!color) color = "base"
84
85 return toggleable({
86 state: {
87 inactive: text_button({ variant, color, margin }),
88 active: text_button({
89 variant,
90 color: active_color ? active_color : color,
91 margin,
92 layer: theme.middle,
93 }),
94 },
95 })
96}