text_button.ts

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