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