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 = options.variant === Button.variant.Ghost ? null : background(layer, options.background ?? color)
93
94 const m = {
95 top: options.margin?.top ?? 0,
96 bottom: options.margin?.bottom ?? 0,
97 left: options.margin?.left ?? 0,
98 right: options.margin?.right ?? 0,
99 }
100 const size = options.size || Button.size.Medium
101 const padding = 2
102
103 const base: BaseStyle = {
104 background: background_color,
105 corder_radius: Button.CORNER_RADIUS,
106 padding: {
107 top: padding,
108 bottom: padding,
109 left: options.shape === Button.shape.Rectangle ? padding + Button.RECTANGLE_PADDING : padding,
110 right: options.shape === Button.shape.Rectangle ? padding + Button.RECTANGLE_PADDING : padding
111 },
112 margin: m,
113 button_height: 16,
114 }
115
116 return base
117 }
118}