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