2023-06-28 17:35:28 +00:00
|
|
|
import { interactive, toggleable } from "../element"
|
2023-06-28 22:20:43 +00:00
|
|
|
import { background, foreground } from "../style_tree/components"
|
2023-08-16 16:38:44 +00:00
|
|
|
import { useTheme, Theme, Layer } from "../theme"
|
|
|
|
import { Button } from "./button"
|
2023-06-27 20:20:45 +00:00
|
|
|
|
|
|
|
export type Margin = {
|
2023-06-28 17:35:28 +00:00
|
|
|
top: number
|
|
|
|
bottom: number
|
|
|
|
left: number
|
|
|
|
right: number
|
2023-06-27 20:20:45 +00:00
|
|
|
}
|
2023-06-27 15:34:12 +00:00
|
|
|
|
|
|
|
interface IconButtonOptions {
|
2023-08-02 19:15:39 +00:00
|
|
|
layer?:
|
|
|
|
| Theme["lowest"]
|
|
|
|
| Theme["middle"]
|
|
|
|
| Theme["highest"]
|
2023-07-04 05:20:56 +00:00
|
|
|
color?: keyof Theme["lowest"]
|
2023-06-28 17:35:28 +00:00
|
|
|
margin?: Partial<Margin>
|
2023-08-16 16:38:44 +00:00
|
|
|
variant?: Button.Variant
|
|
|
|
size?: Button.Size
|
2023-06-27 15:34:12 +00:00
|
|
|
}
|
|
|
|
|
2023-06-28 17:35:28 +00:00
|
|
|
type ToggleableIconButtonOptions = IconButtonOptions & {
|
2023-07-04 05:20:56 +00:00
|
|
|
active_color?: keyof Theme["lowest"]
|
2023-08-16 16:38:44 +00:00
|
|
|
active_layer?: Layer
|
2023-06-28 17:35:28 +00:00
|
|
|
}
|
2023-06-27 16:24:19 +00:00
|
|
|
|
2023-08-16 16:38:44 +00:00
|
|
|
export function icon_button({ color, margin, layer, variant, size }: IconButtonOptions = {
|
|
|
|
variant: Button.variant.Default,
|
|
|
|
size: Button.size.Medium,
|
|
|
|
}) {
|
2023-07-04 04:13:04 +00:00
|
|
|
const theme = useTheme()
|
|
|
|
|
2023-06-28 17:35:28 +00:00
|
|
|
if (!color) color = "base"
|
2023-06-27 15:34:12 +00:00
|
|
|
|
2023-08-16 16:38:44 +00:00
|
|
|
const background_color = variant === Button.variant.Ghost ? null : background(layer ?? theme.lowest, color)
|
2023-08-14 19:13:57 +00:00
|
|
|
|
2023-06-27 15:34:12 +00:00
|
|
|
const m = {
|
|
|
|
top: margin?.top ?? 0,
|
|
|
|
bottom: margin?.bottom ?? 0,
|
|
|
|
left: margin?.left ?? 0,
|
|
|
|
right: margin?.right ?? 0,
|
|
|
|
}
|
|
|
|
|
2023-08-16 16:38:44 +00:00
|
|
|
const padding = {
|
|
|
|
top: size === Button.size.Small ? 0 : 2,
|
|
|
|
bottom: size === Button.size.Small ? 0 : 2,
|
|
|
|
left: size === Button.size.Small ? 0 : 4,
|
|
|
|
right: size === Button.size.Small ? 0 : 4,
|
|
|
|
}
|
|
|
|
|
2023-06-27 15:34:12 +00:00
|
|
|
return interactive({
|
|
|
|
base: {
|
2023-06-27 16:24:19 +00:00
|
|
|
corner_radius: 6,
|
2023-08-16 16:38:44 +00:00
|
|
|
padding: padding,
|
2023-06-27 15:34:12 +00:00
|
|
|
margin: m,
|
2023-06-28 14:19:30 +00:00
|
|
|
icon_width: 14,
|
|
|
|
icon_height: 14,
|
|
|
|
button_width: 20,
|
|
|
|
button_height: 16,
|
2023-06-27 15:34:12 +00:00
|
|
|
},
|
|
|
|
state: {
|
|
|
|
default: {
|
2023-08-14 19:13:57 +00:00
|
|
|
background: background_color,
|
2023-06-27 16:24:19 +00:00
|
|
|
color: foreground(layer ?? theme.lowest, color),
|
2023-06-27 15:34:12 +00:00
|
|
|
},
|
|
|
|
hovered: {
|
2023-06-27 16:24:19 +00:00
|
|
|
background: background(layer ?? theme.lowest, color, "hovered"),
|
|
|
|
color: foreground(layer ?? theme.lowest, color, "hovered"),
|
2023-06-27 15:34:12 +00:00
|
|
|
},
|
|
|
|
clicked: {
|
2023-06-27 16:24:19 +00:00
|
|
|
background: background(layer ?? theme.lowest, color, "pressed"),
|
|
|
|
color: foreground(layer ?? theme.lowest, color, "pressed"),
|
2023-06-27 15:34:12 +00:00
|
|
|
},
|
|
|
|
},
|
2023-06-28 17:35:28 +00:00
|
|
|
})
|
2023-06-27 15:34:12 +00:00
|
|
|
}
|
2023-06-27 16:24:19 +00:00
|
|
|
|
2023-06-28 17:35:28 +00:00
|
|
|
export function toggleable_icon_button(
|
2023-07-04 05:20:56 +00:00
|
|
|
theme: Theme,
|
2023-08-16 16:38:44 +00:00
|
|
|
{ color, active_color, margin, variant, size, active_layer }: ToggleableIconButtonOptions
|
2023-06-28 17:35:28 +00:00
|
|
|
) {
|
|
|
|
if (!color) color = "base"
|
2023-06-27 16:24:19 +00:00
|
|
|
|
|
|
|
return toggleable({
|
|
|
|
state: {
|
2023-08-16 16:38:44 +00:00
|
|
|
inactive: icon_button({ color, margin, variant, size }),
|
2023-07-04 04:13:04 +00:00
|
|
|
active: icon_button({
|
2023-06-28 17:35:28 +00:00
|
|
|
color: active_color ? active_color : color,
|
|
|
|
margin,
|
2023-08-16 16:38:44 +00:00
|
|
|
layer: active_layer,
|
|
|
|
size
|
2023-06-28 17:35:28 +00:00
|
|
|
}),
|
|
|
|
},
|
2023-06-27 16:24:19 +00:00
|
|
|
})
|
|
|
|
}
|