zed/styles/src/component/icon_button.ts

98 lines
2.7 KiB
TypeScript
Raw Normal View History

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"
export type Margin = {
2023-06-28 17:35:28 +00:00
top: number
bottom: number
left: number
right: number
}
2023-06-27 15:34:12 +00:00
interface IconButtonOptions {
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,
}) {
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 }),
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
})
}