1import { font_sizes, useTheme } from "../common"
2import { Layer, Theme } from "../theme"
3import { TextStyle, background } from "../style_tree/components"
4
5// eslint-disable-next-line @typescript-eslint/no-namespace
6export namespace Button {
7 export type Options = {
8 layer: Layer
9 background: keyof Theme["lowest"]
10 color: keyof Theme["lowest"]
11 variant: Button.Variant
12 size: Button.Size
13 shape: Button.Shape
14 margin: {
15 top?: number
16 bottom?: number
17 left?: number
18 right?: number
19 }
20 states: {
21 enabled?: boolean
22 hovered?: boolean
23 pressed?: boolean
24 focused?: boolean
25 disabled?: boolean
26 }
27 }
28
29 export type ToggleableOptions = Options & {
30 active_background: keyof Theme["lowest"]
31 active_color: keyof Theme["lowest"]
32 }
33
34 /** Padding added to each side of a Shape.Rectangle button */
35 export const RECTANGLE_PADDING = 2
36 export const FONT_SIZE = font_sizes.sm
37 export const ICON_SIZE = 14
38 export const CORNER_RADIUS = 6
39
40 export const variant = {
41 Default: "filled",
42 Outline: "outline",
43 Ghost: "ghost",
44 } as const
45
46 export type Variant = (typeof variant)[keyof typeof variant]
47
48 export const shape = {
49 Rectangle: "rectangle",
50 Square: "square",
51 } as const
52
53 export type Shape = (typeof shape)[keyof typeof shape]
54
55 export const size = {
56 Small: "sm",
57 Medium: "md",
58 } as const
59
60 export type Size = (typeof size)[keyof typeof size]
61
62 export type BaseStyle = {
63 corder_radius: number
64 background: string | null
65 padding: {
66 top: number
67 bottom: number
68 left: number
69 right: number
70 }
71 margin: Button.Options["margin"]
72 button_height: number
73 }
74
75 export type LabelButtonStyle = BaseStyle & TextStyle
76 // export type IconButtonStyle = ButtonStyle
77
78 export const button_base = (
79 options: Partial<Button.Options> = {
80 variant: Button.variant.Default,
81 shape: Button.shape.Rectangle,
82 states: {
83 hovered: true,
84 pressed: true,
85 },
86 }
87 ): BaseStyle => {
88 const theme = useTheme()
89
90 const layer = options.layer ?? theme.middle
91 const color = options.color ?? "base"
92 const background_color =
93 options.variant === Button.variant.Ghost
94 ? null
95 : background(layer, options.background ?? color)
96
97 const m = {
98 top: options.margin?.top ?? 0,
99 bottom: options.margin?.bottom ?? 0,
100 left: options.margin?.left ?? 0,
101 right: options.margin?.right ?? 0,
102 }
103 const size = options.size || Button.size.Medium
104 const padding = 2
105
106 const base: BaseStyle = {
107 background: background_color,
108 corder_radius: Button.CORNER_RADIUS,
109 padding: {
110 top: padding,
111 bottom: padding,
112 left:
113 options.shape === Button.shape.Rectangle
114 ? padding + Button.RECTANGLE_PADDING
115 : padding,
116 right:
117 options.shape === Button.shape.Rectangle
118 ? padding + Button.RECTANGLE_PADDING
119 : padding,
120 },
121 margin: m,
122 button_height: 16,
123 }
124
125 return base
126 }
127}