icon_button.ts

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