better_ui 0.6.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +257 -212
  3. data/Rakefile +11 -2
  4. data/app/components/better_ui/action_messages_component/action_messages_component.html.erb +48 -0
  5. data/app/components/better_ui/action_messages_component.rb +544 -0
  6. data/app/components/better_ui/application_component.rb +66 -0
  7. data/app/components/better_ui/button_component/button_component.html.erb +31 -0
  8. data/app/components/better_ui/button_component.rb +307 -0
  9. data/app/components/better_ui/card_component/card_component.html.erb +17 -0
  10. data/app/components/better_ui/card_component.rb +460 -0
  11. data/app/components/better_ui/drawer/header_component/header_component.html.erb +24 -0
  12. data/app/components/better_ui/drawer/header_component.rb +238 -0
  13. data/app/components/better_ui/drawer/layout_component/layout_component.html.erb +44 -0
  14. data/app/components/better_ui/drawer/layout_component.rb +270 -0
  15. data/app/components/better_ui/drawer/nav_group_component/nav_group_component.html.erb +10 -0
  16. data/app/components/better_ui/drawer/nav_group_component.rb +155 -0
  17. data/app/components/better_ui/drawer/nav_item_component/nav_item_component.html.erb +13 -0
  18. data/app/components/better_ui/drawer/nav_item_component.rb +225 -0
  19. data/app/components/better_ui/drawer/sidebar_component/sidebar_component.html.erb +17 -0
  20. data/app/components/better_ui/drawer/sidebar_component.rb +263 -0
  21. data/app/components/better_ui/forms/base_component.rb +450 -0
  22. data/app/components/better_ui/forms/checkbox_component/checkbox_component.html.erb +28 -0
  23. data/app/components/better_ui/forms/checkbox_component.rb +419 -0
  24. data/app/components/better_ui/forms/checkbox_group_component/checkbox_group_component.html.erb +40 -0
  25. data/app/components/better_ui/forms/checkbox_group_component.rb +363 -0
  26. data/app/components/better_ui/forms/number_input_component/number_input_component.html.erb +40 -0
  27. data/app/components/better_ui/forms/number_input_component.rb +320 -0
  28. data/app/components/better_ui/forms/password_input_component/password_input_component.html.erb +71 -0
  29. data/app/components/better_ui/forms/password_input_component.rb +206 -0
  30. data/app/components/better_ui/forms/text_input_component/text_input_component.html.erb +40 -0
  31. data/app/components/better_ui/forms/text_input_component.rb +258 -0
  32. data/app/components/better_ui/forms/textarea_component/textarea_component.html.erb +40 -0
  33. data/app/components/better_ui/forms/textarea_component.rb +329 -0
  34. data/app/form_builders/better_ui/ui_form_builder.rb +467 -0
  35. data/app/helpers/better_ui/application_helper.rb +325 -58
  36. data/app/views/layouts/better_ui/application.html.erb +1 -1
  37. data/config/routes.rb +1 -0
  38. data/lib/better_ui/engine.rb +34 -5
  39. data/lib/better_ui/version.rb +1 -1
  40. data/lib/better_ui.rb +32 -5
  41. data/lib/generators/better_ui/install/USAGE +44 -0
  42. data/lib/generators/better_ui/install/install_generator.rb +87 -0
  43. data/lib/generators/better_ui/install/templates/better_ui_theme.css.tt +280 -0
  44. data/lib/tasks/better_ui_tasks.rake +39 -4
  45. metadata +55 -203
  46. data/app/components/better_ui/application/card/component.html.erb +0 -20
  47. data/app/components/better_ui/application/card/component.rb +0 -214
  48. data/app/components/better_ui/application/main/component.html.erb +0 -9
  49. data/app/components/better_ui/application/main/component.rb +0 -123
  50. data/app/components/better_ui/application/navbar/component.html.erb +0 -92
  51. data/app/components/better_ui/application/navbar/component.rb +0 -136
  52. data/app/components/better_ui/application/sidebar/component.html.erb +0 -249
  53. data/app/components/better_ui/application/sidebar/component.rb +0 -187
  54. data/app/components/better_ui/general/accordion/component.html.erb +0 -5
  55. data/app/components/better_ui/general/accordion/component.rb +0 -92
  56. data/app/components/better_ui/general/accordion/item_component.html.erb +0 -12
  57. data/app/components/better_ui/general/accordion/item_component.rb +0 -176
  58. data/app/components/better_ui/general/alert/component.html.erb +0 -32
  59. data/app/components/better_ui/general/alert/component.rb +0 -242
  60. data/app/components/better_ui/general/avatar/component.html.erb +0 -20
  61. data/app/components/better_ui/general/avatar/component.rb +0 -301
  62. data/app/components/better_ui/general/badge/component.html.erb +0 -23
  63. data/app/components/better_ui/general/badge/component.rb +0 -248
  64. data/app/components/better_ui/general/breadcrumb/component.html.erb +0 -15
  65. data/app/components/better_ui/general/breadcrumb/component.rb +0 -187
  66. data/app/components/better_ui/general/button/component.html.erb +0 -34
  67. data/app/components/better_ui/general/button/component.rb +0 -214
  68. data/app/components/better_ui/general/divider/component.html.erb +0 -10
  69. data/app/components/better_ui/general/divider/component.rb +0 -226
  70. data/app/components/better_ui/general/dropdown/component.html.erb +0 -28
  71. data/app/components/better_ui/general/dropdown/component.rb +0 -192
  72. data/app/components/better_ui/general/dropdown/divider_component.html.erb +0 -1
  73. data/app/components/better_ui/general/dropdown/divider_component.rb +0 -41
  74. data/app/components/better_ui/general/dropdown/item_component.html.erb +0 -6
  75. data/app/components/better_ui/general/dropdown/item_component.rb +0 -119
  76. data/app/components/better_ui/general/field/component.html.erb +0 -27
  77. data/app/components/better_ui/general/field/component.rb +0 -37
  78. data/app/components/better_ui/general/grid/cell_component.html.erb +0 -3
  79. data/app/components/better_ui/general/grid/cell_component.rb +0 -390
  80. data/app/components/better_ui/general/grid/component.html.erb +0 -3
  81. data/app/components/better_ui/general/grid/component.rb +0 -301
  82. data/app/components/better_ui/general/heading/component.html.erb +0 -22
  83. data/app/components/better_ui/general/heading/component.rb +0 -257
  84. data/app/components/better_ui/general/icon/component.html.erb +0 -7
  85. data/app/components/better_ui/general/icon/component.rb +0 -240
  86. data/app/components/better_ui/general/input/checkbox/component.html.erb +0 -5
  87. data/app/components/better_ui/general/input/checkbox/component.rb +0 -238
  88. data/app/components/better_ui/general/input/datetime/component.html.erb +0 -5
  89. data/app/components/better_ui/general/input/datetime/component.rb +0 -223
  90. data/app/components/better_ui/general/input/pin/component.html.erb +0 -1
  91. data/app/components/better_ui/general/input/pin/component.rb +0 -201
  92. data/app/components/better_ui/general/input/radio/component.html.erb +0 -5
  93. data/app/components/better_ui/general/input/radio/component.rb +0 -230
  94. data/app/components/better_ui/general/input/rating/component.html.erb +0 -4
  95. data/app/components/better_ui/general/input/rating/component.rb +0 -272
  96. data/app/components/better_ui/general/input/select/component.html.erb +0 -78
  97. data/app/components/better_ui/general/input/select/component.rb +0 -249
  98. data/app/components/better_ui/general/input/select/select_component.html.erb +0 -5
  99. data/app/components/better_ui/general/input/select/select_component.rb +0 -37
  100. data/app/components/better_ui/general/input/text/component.html.erb +0 -5
  101. data/app/components/better_ui/general/input/text/component.rb +0 -171
  102. data/app/components/better_ui/general/input/textarea/component.html.erb +0 -5
  103. data/app/components/better_ui/general/input/textarea/component.rb +0 -166
  104. data/app/components/better_ui/general/input/toggle/component.html.erb +0 -5
  105. data/app/components/better_ui/general/input/toggle/component.rb +0 -242
  106. data/app/components/better_ui/general/link/component.html.erb +0 -18
  107. data/app/components/better_ui/general/link/component.rb +0 -258
  108. data/app/components/better_ui/general/modal/component.html.erb +0 -5
  109. data/app/components/better_ui/general/modal/component.rb +0 -47
  110. data/app/components/better_ui/general/modal/modal_component.html.erb +0 -52
  111. data/app/components/better_ui/general/modal/modal_component.rb +0 -160
  112. data/app/components/better_ui/general/pagination/component.html.erb +0 -85
  113. data/app/components/better_ui/general/pagination/component.rb +0 -216
  114. data/app/components/better_ui/general/panel/component.html.erb +0 -28
  115. data/app/components/better_ui/general/panel/component.rb +0 -249
  116. data/app/components/better_ui/general/progress/component.html.erb +0 -11
  117. data/app/components/better_ui/general/progress/component.rb +0 -160
  118. data/app/components/better_ui/general/spinner/component.html.erb +0 -35
  119. data/app/components/better_ui/general/spinner/component.rb +0 -93
  120. data/app/components/better_ui/general/table/component.html.erb +0 -5
  121. data/app/components/better_ui/general/table/component.rb +0 -217
  122. data/app/components/better_ui/general/table/tbody_component.html.erb +0 -3
  123. data/app/components/better_ui/general/table/tbody_component.rb +0 -30
  124. data/app/components/better_ui/general/table/td_component.html.erb +0 -3
  125. data/app/components/better_ui/general/table/td_component.rb +0 -44
  126. data/app/components/better_ui/general/table/tfoot_component.html.erb +0 -3
  127. data/app/components/better_ui/general/table/tfoot_component.rb +0 -28
  128. data/app/components/better_ui/general/table/th_component.html.erb +0 -6
  129. data/app/components/better_ui/general/table/th_component.rb +0 -51
  130. data/app/components/better_ui/general/table/thead_component.html.erb +0 -3
  131. data/app/components/better_ui/general/table/thead_component.rb +0 -28
  132. data/app/components/better_ui/general/table/tr_component.html.erb +0 -3
  133. data/app/components/better_ui/general/table/tr_component.rb +0 -30
  134. data/app/components/better_ui/general/tabs/component.html.erb +0 -11
  135. data/app/components/better_ui/general/tabs/component.rb +0 -120
  136. data/app/components/better_ui/general/tabs/panel_component.html.erb +0 -3
  137. data/app/components/better_ui/general/tabs/panel_component.rb +0 -37
  138. data/app/components/better_ui/general/tabs/tab_component.html.erb +0 -13
  139. data/app/components/better_ui/general/tabs/tab_component.rb +0 -111
  140. data/app/components/better_ui/general/tag/component.html.erb +0 -3
  141. data/app/components/better_ui/general/tag/component.rb +0 -104
  142. data/app/components/better_ui/general/text/component.html.erb +0 -1
  143. data/app/components/better_ui/general/text/component.rb +0 -194
  144. data/app/components/better_ui/general/tooltip/component.html.erb +0 -7
  145. data/app/components/better_ui/general/tooltip/component.rb +0 -239
  146. data/app/helpers/better_ui/application/components/card/card_helper.rb +0 -96
  147. data/app/helpers/better_ui/application/components/card.rb +0 -11
  148. data/app/helpers/better_ui/application/components/main/main_helper.rb +0 -64
  149. data/app/helpers/better_ui/application/components/navbar/navbar_helper.rb +0 -77
  150. data/app/helpers/better_ui/application/components/sidebar/sidebar_helper.rb +0 -51
  151. data/app/helpers/better_ui/general/components/accordion/accordion_helper.rb +0 -73
  152. data/app/helpers/better_ui/general/components/alert/alert_helper.rb +0 -57
  153. data/app/helpers/better_ui/general/components/avatar/avatar_helper.rb +0 -29
  154. data/app/helpers/better_ui/general/components/badge/badge_helper.rb +0 -53
  155. data/app/helpers/better_ui/general/components/breadcrumb/breadcrumb_helper.rb +0 -37
  156. data/app/helpers/better_ui/general/components/button/button_helper.rb +0 -65
  157. data/app/helpers/better_ui/general/components/container/container_helper.rb +0 -60
  158. data/app/helpers/better_ui/general/components/divider/divider_helper.rb +0 -63
  159. data/app/helpers/better_ui/general/components/dropdown/divider_helper.rb +0 -32
  160. data/app/helpers/better_ui/general/components/dropdown/dropdown_helper.rb +0 -88
  161. data/app/helpers/better_ui/general/components/dropdown/item_helper.rb +0 -68
  162. data/app/helpers/better_ui/general/components/field/field_helper.rb +0 -26
  163. data/app/helpers/better_ui/general/components/grid/grid_helper.rb +0 -145
  164. data/app/helpers/better_ui/general/components/heading/heading_helper.rb +0 -72
  165. data/app/helpers/better_ui/general/components/icon/icon_helper.rb +0 -16
  166. data/app/helpers/better_ui/general/components/input/checkbox/checkbox_helper.rb +0 -81
  167. data/app/helpers/better_ui/general/components/input/datetime/datetime_helper.rb +0 -91
  168. data/app/helpers/better_ui/general/components/input/pin/pin_helper.rb +0 -76
  169. data/app/helpers/better_ui/general/components/input/radio/radio_helper.rb +0 -79
  170. data/app/helpers/better_ui/general/components/input/radio_group/radio_group_helper.rb +0 -124
  171. data/app/helpers/better_ui/general/components/input/rating/rating_helper.rb +0 -70
  172. data/app/helpers/better_ui/general/components/input/select/select_helper.rb +0 -86
  173. data/app/helpers/better_ui/general/components/input/text/text_helper.rb +0 -138
  174. data/app/helpers/better_ui/general/components/input/textarea/textarea_helper.rb +0 -73
  175. data/app/helpers/better_ui/general/components/input/toggle/toggle_helper.rb +0 -77
  176. data/app/helpers/better_ui/general/components/link/link_helper.rb +0 -89
  177. data/app/helpers/better_ui/general/components/modal/modal_helper.rb +0 -85
  178. data/app/helpers/better_ui/general/components/pagination/pagination_helper.rb +0 -82
  179. data/app/helpers/better_ui/general/components/panel/panel_helper.rb +0 -83
  180. data/app/helpers/better_ui/general/components/progress/progress_helper.rb +0 -53
  181. data/app/helpers/better_ui/general/components/spinner/spinner_helper.rb +0 -19
  182. data/app/helpers/better_ui/general/components/table/table_helper.rb +0 -53
  183. data/app/helpers/better_ui/general/components/table/tbody_helper.rb +0 -13
  184. data/app/helpers/better_ui/general/components/table/td_helper.rb +0 -19
  185. data/app/helpers/better_ui/general/components/table/tfoot_helper.rb +0 -13
  186. data/app/helpers/better_ui/general/components/table/th_helper.rb +0 -19
  187. data/app/helpers/better_ui/general/components/table/thead_helper.rb +0 -13
  188. data/app/helpers/better_ui/general/components/table/tr_helper.rb +0 -13
  189. data/app/helpers/better_ui/general/components/tabs/panel_helper.rb +0 -62
  190. data/app/helpers/better_ui/general/components/tabs/tab_helper.rb +0 -55
  191. data/app/helpers/better_ui/general/components/tabs/tabs_helper.rb +0 -95
  192. data/app/helpers/better_ui/general/components/tag/tag_helper.rb +0 -26
  193. data/app/helpers/better_ui/general/components/text/text_helper.rb +0 -83
  194. data/app/helpers/better_ui/general/components/tooltip/tooltip_helper.rb +0 -60
  195. data/app/jobs/better_ui/application_job.rb +0 -4
  196. data/app/mailers/better_ui/application_mailer.rb +0 -6
  197. data/config/initializers/lookbook.rb +0 -23
  198. data/lib/better_ui/railtie.rb +0 -20
@@ -0,0 +1,307 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterUi
4
+ class ButtonComponent < ApplicationComponent
5
+ renders_one :icon_before
6
+ renders_one :icon_after
7
+
8
+ SIZES = {
9
+ xs: { padding: "px-2 py-1", text: "text-xs", icon: "w-3 h-3", gap: "gap-1" },
10
+ sm: { padding: "px-3 py-1.5", text: "text-sm", icon: "w-4 h-4", gap: "gap-1.5" },
11
+ md: { padding: "px-4 py-2", text: "text-base", icon: "w-5 h-5", gap: "gap-2" },
12
+ lg: { padding: "px-5 py-2.5", text: "text-lg", icon: "w-6 h-6", gap: "gap-2.5" },
13
+ xl: { padding: "px-6 py-3", text: "text-xl", icon: "w-7 h-7", gap: "gap-3" }
14
+ }.freeze
15
+
16
+ STYLES = %i[solid outline ghost soft].freeze
17
+ TYPES = %i[button submit reset].freeze
18
+
19
+ def initialize(
20
+ variant: :primary,
21
+ style: :solid,
22
+ size: :md,
23
+ show_loader: false,
24
+ show_loader_on_click: false,
25
+ disabled: false,
26
+ type: :button,
27
+ href: nil,
28
+ target: nil,
29
+ rel: nil,
30
+ method: nil,
31
+ container_classes: nil,
32
+ **options
33
+ )
34
+ @variant = validate_variant(variant)
35
+ @style = validate_style(style)
36
+ @size = validate_size(size)
37
+ @show_loader = show_loader
38
+ @show_loader_on_click = show_loader_on_click
39
+ @disabled = disabled
40
+ @type = validate_type(type) unless href
41
+ @href = href
42
+ @target = target
43
+ @rel = compute_rel(target, rel)
44
+ @method = method
45
+ @container_classes = container_classes
46
+ @options = options
47
+ end
48
+
49
+ def link?
50
+ @href.present?
51
+ end
52
+
53
+ private
54
+
55
+ attr_reader :variant, :style, :size, :show_loader, :show_loader_on_click, :disabled, :type,
56
+ :href, :target, :rel, :method, :container_classes, :options
57
+
58
+ def component_classes
59
+ css_classes([
60
+ base_classes,
61
+ style_classes,
62
+ size_classes,
63
+ state_classes,
64
+ @container_classes
65
+ ].flatten.compact)
66
+ end
67
+
68
+ def component_attributes
69
+ link? ? link_attributes : button_attributes
70
+ end
71
+
72
+ def button_attributes
73
+ data_attrs = {
74
+ controller: "better-ui--button",
75
+ action: "click->better-ui--button#handleClick"
76
+ }
77
+
78
+ data_attrs[:"better-ui--button-show-loader-on-click-value"] = @show_loader_on_click if @show_loader_on_click
79
+
80
+ {
81
+ type: @type,
82
+ disabled: @disabled || @show_loader,
83
+ data: data_attrs,
84
+ **@options
85
+ }
86
+ end
87
+
88
+ def link_attributes
89
+ data_attrs = {
90
+ controller: "better-ui--button",
91
+ action: "click->better-ui--button#handleClick"
92
+ }
93
+
94
+ data_attrs[:"better-ui--button-show-loader-on-click-value"] = @show_loader_on_click if @show_loader_on_click
95
+ data_attrs[:turbo_method] = @method if @method
96
+
97
+ attrs = {
98
+ href: disabled_or_loading? ? nil : @href,
99
+ target: @target,
100
+ rel: @rel,
101
+ data: data_attrs,
102
+ **@options
103
+ }
104
+
105
+ if disabled_or_loading?
106
+ attrs[:"aria-disabled"] = "true"
107
+ attrs[:tabindex] = "-1"
108
+ end
109
+
110
+ attrs.compact
111
+ end
112
+
113
+ def disabled_or_loading?
114
+ @disabled || @show_loader
115
+ end
116
+
117
+ def compute_rel(target, rel)
118
+ return rel if rel.present?
119
+ return "noopener noreferrer" if target == "_blank"
120
+ nil
121
+ end
122
+
123
+ def base_classes
124
+ ring_class = case @variant
125
+ when :primary then "focus:ring-primary-500"
126
+ when :secondary then "focus:ring-secondary-500"
127
+ when :accent then "focus:ring-accent-500"
128
+ when :success then "focus:ring-success-500"
129
+ when :danger then "focus:ring-danger-500"
130
+ when :warning then "focus:ring-warning-500"
131
+ when :info then "focus:ring-info-500"
132
+ when :light then "focus:ring-grayscale-400"
133
+ when :dark then "focus:ring-grayscale-600"
134
+ end
135
+
136
+ [
137
+ "inline-flex items-center justify-center",
138
+ "font-medium rounded-lg",
139
+ "transition-all duration-200",
140
+ "focus:outline-none focus:ring-2 focus:ring-offset-2",
141
+ ring_class
142
+ ]
143
+ end
144
+
145
+ def style_classes
146
+ case @style
147
+ when :solid then solid_classes
148
+ when :outline then outline_classes
149
+ when :ghost then ghost_classes
150
+ when :soft then soft_classes
151
+ end
152
+ end
153
+
154
+ def solid_classes
155
+ bg_classes = case @variant
156
+ when :primary
157
+ [ "bg-primary-600", "hover:bg-primary-700", "active:bg-primary-800" ]
158
+ when :secondary
159
+ [ "bg-secondary-600", "hover:bg-secondary-700", "active:bg-secondary-800" ]
160
+ when :accent
161
+ [ "bg-accent-600", "hover:bg-accent-700", "active:bg-accent-800" ]
162
+ when :success
163
+ [ "bg-success-600", "hover:bg-success-700", "active:bg-success-800" ]
164
+ when :danger
165
+ [ "bg-danger-600", "hover:bg-danger-700", "active:bg-danger-800" ]
166
+ when :warning
167
+ [ "bg-warning-600", "hover:bg-warning-700", "active:bg-warning-800" ]
168
+ when :info
169
+ [ "bg-info-600", "hover:bg-info-700", "active:bg-info-800" ]
170
+ when :light
171
+ [ "bg-grayscale-100", "hover:bg-grayscale-200", "active:bg-grayscale-300" ]
172
+ when :dark
173
+ [ "bg-grayscale-900", "hover:bg-grayscale-800", "active:bg-grayscale-700" ]
174
+ end
175
+
176
+ bg_classes + [ text_color_for_solid ]
177
+ end
178
+
179
+ def outline_classes
180
+ color_classes = case @variant
181
+ when :primary
182
+ [ "border-primary-600", "hover:border-primary-700", "hover:bg-primary-50", "text-primary-600" ]
183
+ when :secondary
184
+ [ "border-secondary-600", "hover:border-secondary-700", "hover:bg-secondary-50", "text-secondary-600" ]
185
+ when :accent
186
+ [ "border-accent-600", "hover:border-accent-700", "hover:bg-accent-50", "text-accent-600" ]
187
+ when :success
188
+ [ "border-success-600", "hover:border-success-700", "hover:bg-success-50", "text-success-600" ]
189
+ when :danger
190
+ [ "border-danger-600", "hover:border-danger-700", "hover:bg-danger-50", "text-danger-600" ]
191
+ when :warning
192
+ [ "border-warning-600", "hover:border-warning-700", "hover:bg-warning-50", "text-warning-600" ]
193
+ when :info
194
+ [ "border-info-600", "hover:border-info-700", "hover:bg-info-50", "text-info-600" ]
195
+ when :light
196
+ [ "border-grayscale-400", "hover:border-grayscale-500", "hover:bg-grayscale-50", "text-grayscale-400", "hover:text-grayscale-500" ]
197
+ when :dark
198
+ [ "border-grayscale-700", "hover:border-grayscale-600", "hover:bg-grayscale-600", "text-grayscale-700", "hover:text-grayscale-50" ]
199
+ end
200
+
201
+ [ "bg-transparent", "border-2" ] + color_classes
202
+ end
203
+
204
+ def ghost_classes
205
+ color_classes = case @variant
206
+ when :primary
207
+ [ "hover:bg-primary-50", "active:bg-primary-100", "text-primary-600" ]
208
+ when :secondary
209
+ [ "hover:bg-secondary-50", "active:bg-secondary-100", "text-secondary-600" ]
210
+ when :accent
211
+ [ "hover:bg-accent-50", "active:bg-accent-100", "text-accent-600" ]
212
+ when :success
213
+ [ "hover:bg-success-50", "active:bg-success-100", "text-success-600" ]
214
+ when :danger
215
+ [ "hover:bg-danger-50", "active:bg-danger-100", "text-danger-600" ]
216
+ when :warning
217
+ [ "hover:bg-warning-50", "active:bg-warning-100", "text-warning-600" ]
218
+ when :info
219
+ [ "hover:bg-info-50", "active:bg-info-100", "text-info-600" ]
220
+ when :light
221
+ [ "hover:bg-grayscale-100", "active:bg-grayscale-200", "text-grayscale-700" ]
222
+ when :dark
223
+ [ "hover:bg-grayscale-800", "active:bg-grayscale-700", "text-grayscale-700", "hover:text-grayscale-50" ]
224
+ end
225
+
226
+ [ "bg-transparent" ] + color_classes
227
+ end
228
+
229
+ def soft_classes
230
+ case @variant
231
+ when :primary
232
+ [ "bg-primary-100", "hover:bg-primary-200", "active:bg-primary-300", "text-primary-700" ]
233
+ when :secondary
234
+ [ "bg-secondary-100", "hover:bg-secondary-200", "active:bg-secondary-300", "text-secondary-700" ]
235
+ when :accent
236
+ [ "bg-accent-100", "hover:bg-accent-200", "active:bg-accent-300", "text-accent-700" ]
237
+ when :success
238
+ [ "bg-success-100", "hover:bg-success-200", "active:bg-success-300", "text-success-700" ]
239
+ when :danger
240
+ [ "bg-danger-100", "hover:bg-danger-200", "active:bg-danger-300", "text-danger-700" ]
241
+ when :warning
242
+ [ "bg-warning-100", "hover:bg-warning-200", "active:bg-warning-300", "text-warning-700" ]
243
+ when :info
244
+ [ "bg-info-100", "hover:bg-info-200", "active:bg-info-300", "text-info-700" ]
245
+ when :light
246
+ [ "bg-grayscale-100", "hover:bg-grayscale-200", "active:bg-grayscale-300", "text-grayscale-700" ]
247
+ when :dark
248
+ [ "bg-grayscale-800", "hover:bg-grayscale-700", "active:bg-grayscale-600", "text-grayscale-100" ]
249
+ end
250
+ end
251
+
252
+ def text_color_for_solid
253
+ @variant == :light ? "text-grayscale-900" : "text-grayscale-50"
254
+ end
255
+
256
+ def size_classes
257
+ size_config = SIZES[@size]
258
+ [
259
+ size_config[:padding],
260
+ size_config[:text],
261
+ size_config[:gap]
262
+ ]
263
+ end
264
+
265
+ def state_classes
266
+ classes = []
267
+ if @disabled && !@show_loader
268
+ classes << "opacity-50 cursor-not-allowed"
269
+ classes << "pointer-events-none" if link?
270
+ elsif @show_loader
271
+ classes << "cursor-wait"
272
+ classes << "pointer-events-none" if link?
273
+ else
274
+ classes << "cursor-pointer"
275
+ end
276
+ classes
277
+ end
278
+
279
+ def validate_variant(variant)
280
+ unless BetterUi::ApplicationComponent::VARIANTS.key?(variant)
281
+ raise ArgumentError, "Invalid variant: #{variant}. Must be one of: #{BetterUi::ApplicationComponent::VARIANTS.keys.join(", ")}"
282
+ end
283
+ variant
284
+ end
285
+
286
+ def validate_style(style)
287
+ unless STYLES.include?(style)
288
+ raise ArgumentError, "Invalid style: #{style}. Must be one of: #{STYLES.join(", ")}"
289
+ end
290
+ style
291
+ end
292
+
293
+ def validate_size(size)
294
+ unless SIZES.key?(size)
295
+ raise ArgumentError, "Invalid size: #{size}. Must be one of: #{SIZES.keys.join(", ")}"
296
+ end
297
+ size
298
+ end
299
+
300
+ def validate_type(type)
301
+ unless TYPES.include?(type)
302
+ raise ArgumentError, "Invalid type: #{type}. Must be one of: #{TYPES.join(", ")}"
303
+ end
304
+ type
305
+ end
306
+ end
307
+ end
@@ -0,0 +1,17 @@
1
+ <div class="<%= component_classes %>" <%= tag.attributes(html_attributes) %>>
2
+ <% if header? %>
3
+ <div class="<%= header_wrapper_classes %>">
4
+ <%= header %>
5
+ </div>
6
+ <% end %>
7
+
8
+ <div class="<%= body_wrapper_classes %>">
9
+ <%= body? ? body : content %>
10
+ </div>
11
+
12
+ <% if footer? %>
13
+ <div class="<%= footer_wrapper_classes %>">
14
+ <%= footer %>
15
+ </div>
16
+ <% end %>
17
+ </div>