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?:
14 | Theme["lowest"]
15 | Theme["middle"]
16 | Theme["highest"]
17 variant?: Button.Variant
18 color?: keyof Theme["lowest"]
19 margin?: Partial<Margin>
20 disabled?: boolean
21 text_properties?: TextProperties
22}
23
24type ToggleableTextButtonOptions = TextButtonOptions & {
25 active_color?: keyof Theme["lowest"]
26}
27
28export function text_button({
29 variant = Button.variant.Default,
30 color,
31 layer,
32 margin,
33 disabled,
34 text_properties,
35}: TextButtonOptions = {}) {
36 const theme = useTheme()
37 if (!color) color = "base"
38
39 const background_color = variant === Button.variant.Ghost ? null : 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:
71 disabled
72 ? foreground(layer ?? theme.lowest, "disabled")
73 : foreground(layer ?? theme.lowest, color),
74 },
75 hovered:
76 disabled ? {} : {
77 background: background(layer ?? theme.lowest, color, "hovered"),
78 color: foreground(layer ?? theme.lowest, color, "hovered"),
79 },
80 clicked: disabled ? {} : {
81 background: background(layer ?? theme.lowest, color, "pressed"),
82 color: foreground(layer ?? theme.lowest, color, "pressed"),
83 },
84 },
85 })
86}
87
88export function toggleable_text_button(
89 theme: Theme,
90 { variant, color, active_color, margin }: ToggleableTextButtonOptions = {}
91) {
92 if (!color) color = "base"
93
94 return toggleable({
95 state: {
96 inactive: text_button({ variant, color, margin }),
97 active: text_button({
98 variant,
99 color: active_color ? active_color : color,
100 margin,
101 layer: theme.middle,
102 }),
103 },
104 })
105}