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