icon_button.ts

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