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