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
@@ -1,249 +0,0 @@
1
- <div data-controller="bui-sidebar"
2
- data-bui-sidebar-width-value="<%= @width == :md ? 256 : 320 %>"
3
- data-bui-sidebar-min-width-value="200"
4
- data-bui-sidebar-max-width-value="400"
5
- data-bui-sidebar-pinned-value="true"
6
- class="<%= wrapper_classes %>">
7
-
8
- <!-- Mobile Overlay -->
9
- <div data-bui-sidebar-target="overlay" class="fixed inset-0 bg-black bg-opacity-50 z-40 hidden md:hidden"></div>
10
-
11
- <!-- Sidebar Container -->
12
- <aside data-bui-sidebar-target="container" class="<%= container_classes %>">
13
- <!-- Header Section -->
14
- <% if has_header? %>
15
- <div class="px-6 py-4 border-b border-gray-200">
16
- <div class="flex items-center justify-between">
17
- <% if header[:logo].present? %>
18
- <div class="flex items-center">
19
- <div class="flex-shrink-0">
20
- <% if header[:logo].is_a?(Hash) %>
21
- <%= bui_avatar(**header[:logo]) %>
22
- <% else %>
23
- <%= header[:logo].html_safe %>
24
- <% end %>
25
- </div>
26
- <% if header[:title].present? %>
27
- <div class="ml-3">
28
- <h2 class="text-lg font-semibold text-gray-900"><%= header[:title] %></h2>
29
- <% if header[:subtitle].present? %>
30
- <p class="text-sm text-gray-500"><%= header[:subtitle] %></p>
31
- <% end %>
32
- </div>
33
- <% end %>
34
- </div>
35
- <% elsif header[:title].present? %>
36
- <div>
37
- <h2 class="text-lg font-semibold text-gray-900"><%= header[:title] %></h2>
38
- <% if header[:subtitle].present? %>
39
- <p class="text-sm text-gray-500"><%= header[:subtitle] %></p>
40
- <% end %>
41
- </div>
42
- <% end %>
43
-
44
- <!-- Collapse Button (solo se collapsible) -->
45
- <% if collapsible %>
46
- <%= bui_button(
47
- icon: "arrow-left",
48
- type: :white,
49
- size: :small,
50
- title: "Comprimi sidebar"
51
- ) %>
52
- <% end %>
53
- </div>
54
- </div>
55
- <% end %>
56
-
57
- <!-- Navigation Section -->
58
- <nav class="flex-1 px-4 py-6 space-y-6 overflow-y-auto">
59
- <% navigation_sections.each do |section| %>
60
- <div class="space-y-2">
61
- <!-- Section Title -->
62
- <% if section[:title].present? %>
63
- <% if section[:href] %>
64
- <%= link_to section[:href], class: "px-3 text-xs font-semibold text-gray-500 uppercase tracking-wider" do %>
65
- <%= section[:title] %>
66
- <% end %>
67
- <% else %>
68
- <h3 class="px-3 text-xs font-semibold text-gray-500 uppercase tracking-wider">
69
- <%= section[:title] %>
70
- </h3>
71
- <% end %>
72
- <% end %>
73
-
74
- <!-- Navigation Items -->
75
- <div class="space-y-1">
76
- <% (section[:items] || []).each do |item| %>
77
- <% if item[:type] == :collapsible && collapsible %>
78
- <!-- Collapsible Section -->
79
- <div>
80
- <button
81
- type="button"
82
- class="group flex items-center justify-between w-full px-3 py-2 text-sm font-medium text-gray-700 rounded-md hover:bg-gray-50 hover:text-gray-900 transition-colors duration-150"
83
- data-bui-sidebar-target="sectionTrigger"
84
- data-bui-sidebar-section-id="<%= item[:id] %>"
85
- data-action="click->bui-sidebar#toggleSection"
86
- aria-expanded="<%= item[:expanded] || false %>"
87
- >
88
- <div class="flex items-center">
89
- <% if item[:icon].present? %>
90
- <span class="mr-3 text-gray-400 group-hover:text-gray-500">
91
- <%= bui_icon(item[:icon], size: :medium) %>
92
- </span>
93
- <% end %>
94
- <span><%= item[:label] %></span>
95
- </div>
96
- <span class="ml-3 transform transition-transform duration-150 <%= 'rotate-90' if item[:expanded] %>" data-bui-sidebar-chevron>
97
- <%= bui_icon("chevron-right", size: :small) %>
98
- </span>
99
- </button>
100
-
101
- <div
102
- data-bui-sidebar-target="sectionContent"
103
- data-bui-sidebar-section-id="<%= item[:id] %>"
104
- class="<%= item[:expanded] ? 'block' : 'hidden' %> mt-1 space-y-1"
105
- >
106
- <% (item[:children] || []).each do |child| %>
107
- <% if child[:href].present? %>
108
- <a
109
- href="<%= child[:href] %>"
110
- class="<%= (child[:active] || false) ? 'group flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors duration-150 bg-gray-100 text-gray-900' : 'group flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors duration-150 text-gray-700 hover:bg-gray-50 hover:text-gray-900' %> pl-11"
111
- >
112
- <% if child[:icon].present? %>
113
- <span class="mr-3">
114
- <%= bui_icon(child[:icon], size: :small) %>
115
- </span>
116
- <% end %>
117
- <%= child[:label] %>
118
- </a>
119
- <% else %>
120
- <div class="<%= (child[:active] || false) ? 'group flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors duration-150 bg-gray-100 text-gray-900' : 'group flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors duration-150 text-gray-700 hover:bg-gray-50 hover:text-gray-900' %> pl-11 cursor-default">
121
- <% if child[:icon].present? %>
122
- <span class="mr-3">
123
- <%= bui_icon(child[:icon], size: :small) %>
124
- </span>
125
- <% end %>
126
- <%= child[:label] %>
127
- </div>
128
- <% end %>
129
- <% end %>
130
- </div>
131
- </div>
132
- <% else %>
133
- <!-- Regular Navigation Item -->
134
- <% if item[:href].present? %>
135
- <a
136
- href="<%= item[:href] %>"
137
- class="<%= (item[:active] || false) ? 'group flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors duration-150 bg-gray-100 text-gray-900' : 'group flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors duration-150 text-gray-700 hover:bg-gray-50 hover:text-gray-900' %>"
138
- >
139
- <% if item[:icon].present? %>
140
- <span class="mr-3 text-gray-400 group-hover:text-gray-500">
141
- <%= bui_icon(item[:icon], size: :medium) %>
142
- </span>
143
- <% end %>
144
- <%= item[:label] %>
145
- <% if item[:badge].present? %>
146
- <span class="ml-auto inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800">
147
- <%= item[:badge] %>
148
- </span>
149
- <% end %>
150
- </a>
151
- <% else %>
152
- <div class="<%= (item[:active] || false) ? 'group flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors duration-150 bg-gray-100 text-gray-900' : 'group flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors duration-150 text-gray-700 hover:bg-gray-50 hover:text-gray-900' %> cursor-default">
153
- <% if item[:icon].present? %>
154
- <span class="mr-3 text-gray-400">
155
- <%= bui_icon(item[:icon], size: :medium) %>
156
- </span>
157
- <% end %>
158
- <%= item[:label] %>
159
- <% if item[:badge].present? %>
160
- <span class="ml-auto inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800">
161
- <%= item[:badge] %>
162
- </span>
163
- <% end %>
164
- </div>
165
- <% end %>
166
- <% end %>
167
- <% end %>
168
- </div>
169
- </div>
170
- <% end %>
171
-
172
- <%= content if content.present? %>
173
- </nav>
174
-
175
- <!-- Footer Section -->
176
- <% if has_footer? %>
177
- <div class="px-6 py-4 border-t border-gray-200">
178
- <% if has_user_dropdown? %>
179
- <!-- User Dropdown -->
180
- <% user_dropdown = footer[:user_dropdown] %>
181
- <%= bui_dropdown(
182
- trigger: user_dropdown_trigger,
183
- position: :top,
184
- theme: :white,
185
- fullwidth: true,
186
- show_chevron: false
187
- ) do %>
188
- <% (user_dropdown[:menu_items] || []).each do |item| %>
189
- <%= bui_dropdown_item(
190
- text: item[:text],
191
- icon: item[:icon],
192
- href: item[:href],
193
- theme: item[:theme] || :default,
194
- active: item[:active] || false,
195
- disabled: item[:disabled] || false
196
- ) %>
197
- <% end %>
198
- <% end %>
199
- <% elsif footer[:user_info].present? %>
200
- <div class="flex items-center">
201
- <% if footer[:user_info][:avatar].present? %>
202
- <div class="flex-shrink-0">
203
- <% if footer[:user_info][:avatar].is_a?(Hash) %>
204
- <%= bui_avatar(**footer[:user_info][:avatar]) %>
205
- <% else %>
206
- <%= footer[:user_info][:avatar].html_safe %>
207
- <% end %>
208
- </div>
209
- <% end %>
210
- <div class="<%= footer[:user_info][:avatar].present? ? 'ml-3' : '' %>">
211
- <% if footer[:user_info][:name].present? %>
212
- <p class="text-sm font-medium text-gray-700">
213
- <%= footer[:user_info][:name] %>
214
- </p>
215
- <% end %>
216
- <% if footer[:user_info][:email].present? %>
217
- <p class="text-xs text-gray-500">
218
- <%= footer[:user_info][:email] %>
219
- </p>
220
- <% end %>
221
- </div>
222
- <% if footer[:user_info][:menu_button].present? %>
223
- <div class="ml-auto">
224
- <%= footer[:user_info][:menu_button] %>
225
- </div>
226
- <% end %>
227
- </div>
228
- <% end %>
229
-
230
- <% if footer[:content].present? %>
231
- <div class="<%= (footer[:user_info].present? || has_user_dropdown?) ? 'mt-4' : '' %>">
232
- <%= footer[:content] %>
233
- </div>
234
- <% end %>
235
- </div>
236
- <% end %>
237
-
238
- <!-- Resize Handle (solo se NON collapsible) -->
239
- <% unless collapsible %>
240
- <div data-bui-sidebar-target="resizeHandle"
241
- class="absolute top-0 right-0 w-1 h-full bg-transparent hover:bg-blue-500 cursor-col-resize transition-colors duration-150 group">
242
- <div class="absolute inset-y-0 -right-1 w-3 flex items-center justify-center">
243
- <div class="w-0.5 h-8 bg-gray-300 group-hover:bg-blue-500 transition-colors duration-150"></div>
244
- </div>
245
- </div>
246
- <% end %>
247
- </aside>
248
-
249
- </div>
@@ -1,187 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module BetterUi
4
- module Application
5
- module Sidebar
6
- class Component < ViewComponent::Base
7
- # Include degli helper per utilizzare bui_icon, bui_avatar, bui_button e bui_dropdown
8
- include BetterUi::General::Components::Icon::IconHelper
9
- include BetterUi::General::Components::Avatar::AvatarHelper
10
- include BetterUi::General::Components::Button::ButtonHelper
11
- include BetterUi::General::Components::Dropdown::DropdownHelper
12
- include BetterUi::General::Components::Dropdown::ItemHelper
13
- attr_reader :width, :position, :theme, :shadow, :border, :header, :footer, :navigation_sections, :collapsible, :classes
14
-
15
- # Larghezze sidebar con classi Tailwind dirette
16
- SIDEBAR_WIDTHS = {
17
- sm: "w-48",
18
- md: "w-64",
19
- lg: "w-72",
20
- xl: "w-80"
21
- }
22
-
23
- # Temi sidebar con classi Tailwind dirette
24
- SIDEBAR_THEMES = {
25
- default: "bg-white text-gray-900",
26
- dark: "bg-gray-900 text-white",
27
- light: "bg-white text-gray-900"
28
- }
29
-
30
- # Ombre sidebar con classi Tailwind dirette
31
- SIDEBAR_SHADOWS = {
32
- none: "",
33
- sm: "shadow-sm",
34
- md: "shadow-md",
35
- lg: "shadow-lg",
36
- xl: "shadow-xl"
37
- }
38
-
39
- # Bordi sidebar con classi Tailwind dirette
40
- SIDEBAR_BORDERS = {
41
- left: "border-r border-gray-200",
42
- right: "border-l border-gray-200"
43
- }
44
-
45
- # @param width [Symbol] Larghezza della sidebar (:sm, :md, :lg, :xl), default :md (w-64)
46
- # @param position [Symbol] Posizione della sidebar (:left, :right), default :left
47
- # @param theme [Symbol] Tema colori (:default, :dark, :light), default :default
48
- # @param shadow [Symbol] Tipo di ombra (:none, :sm, :md, :lg), default :lg
49
- # @param border [Boolean] Se mostrare il bordo destro/sinistro, default true
50
- # @param header [Hash] Configurazione header (logo, title, subtitle)
51
- # @param footer [Hash] Configurazione footer (content, user_info, user_dropdown)
52
- # @param navigation_sections [Array] Array di sezioni di navigazione
53
- # @param collapsible [Boolean] Se abilitare sezioni collassabili, default true
54
- # @param classes [String] Classi CSS aggiuntive
55
- def initialize(
56
- width: :md,
57
- position: :left,
58
- theme: :default,
59
- shadow: :lg,
60
- border: true,
61
- header: {},
62
- footer: {},
63
- navigation_sections: [],
64
- collapsible: true,
65
- classes: nil
66
- )
67
- @width = width.to_sym
68
- @position = position.to_sym
69
- @theme = theme.to_sym
70
- @shadow = shadow.to_sym
71
- @border = border
72
- @header = header || {}
73
- @footer = footer || {}
74
- @navigation_sections = navigation_sections || []
75
- @collapsible = collapsible
76
- @classes = classes
77
- end
78
-
79
- def wrapper_classes
80
- base_classes = %w[fixed top-0 inset-y-0 h-screen z-[9999]]
81
-
82
- # Posizione
83
- base_classes << (position == :right ? "right-0" : "left-0")
84
-
85
- # Larghezza
86
- base_classes << width_class
87
-
88
- base_classes.compact.join(" ")
89
- end
90
-
91
- def container_classes
92
- base_classes = %w[flex flex-col h-full]
93
-
94
- # Tema
95
- base_classes.concat(theme_classes)
96
-
97
- # Shadow
98
- base_classes << shadow_class if shadow != :none
99
-
100
- # Border
101
- base_classes << border_class if border
102
-
103
- # Classi aggiuntive
104
- base_classes << classes if classes.present?
105
-
106
- base_classes.compact.join(" ")
107
- end
108
-
109
-
110
- def has_header?
111
- header.present? && (header[:title].present? || header[:logo].present?)
112
- end
113
-
114
- def has_footer?
115
- footer.present? && (footer[:content].present? || footer[:user_info].present? || footer[:user_dropdown].present?)
116
- end
117
-
118
- def has_user_dropdown?
119
- footer.present? && footer[:user_dropdown].present?
120
- end
121
-
122
- def user_dropdown_trigger
123
- return '' unless has_user_dropdown?
124
-
125
- user_dropdown = footer[:user_dropdown]
126
- avatar_html = if user_dropdown[:avatar].present?
127
- if user_dropdown[:avatar].is_a?(Hash)
128
- bui_avatar(**user_dropdown[:avatar])
129
- else
130
- user_dropdown[:avatar].html_safe
131
- end
132
- else
133
- ''
134
- end
135
-
136
- content_tag(:div, class: "flex items-center w-full text-left") do
137
- avatar_section = if user_dropdown[:avatar].present?
138
- content_tag(:div, avatar_html, class: "flex-shrink-0")
139
- else
140
- ''
141
- end
142
-
143
- text_section = content_tag(:div, class: user_dropdown[:avatar].present? ? 'ml-3 min-w-0 flex-1' : 'min-w-0 flex-1') do
144
- name_part = if user_dropdown[:name].present?
145
- content_tag(:p, user_dropdown[:name], class: "text-sm font-medium text-gray-700 truncate")
146
- else
147
- ''
148
- end
149
-
150
- subtitle_part = if user_dropdown[:subtitle].present?
151
- content_tag(:p, user_dropdown[:subtitle], class: "text-xs text-gray-500 truncate")
152
- else
153
- ''
154
- end
155
-
156
- (name_part + subtitle_part).html_safe
157
- end
158
-
159
- chevron_section = content_tag(:div, class: "ml-auto flex-shrink-0") do
160
- bui_icon("chevron-down", size: :small, classes: "text-gray-400")
161
- end
162
-
163
- (avatar_section + text_section + chevron_section).html_safe
164
- end
165
- end
166
-
167
- private
168
-
169
- def width_class
170
- SIDEBAR_WIDTHS[@width] || SIDEBAR_WIDTHS[:md]
171
- end
172
-
173
- def theme_classes
174
- (SIDEBAR_THEMES[@theme] || SIDEBAR_THEMES[:default]).split
175
- end
176
-
177
- def shadow_class
178
- SIDEBAR_SHADOWS[@shadow] || SIDEBAR_SHADOWS[:none]
179
- end
180
-
181
- def border_class
182
- SIDEBAR_BORDERS[@position] || SIDEBAR_BORDERS[:left]
183
- end
184
- end
185
- end
186
- end
187
- end
@@ -1,5 +0,0 @@
1
- <div <%= tag.attributes(wrapper_attributes) %>>
2
- <% items.each do |item| %>
3
- <%= item %>
4
- <% end %>
5
- </div>
@@ -1,92 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module BetterUi
4
- module General
5
- module Accordion
6
- class Component < ViewComponent::Base
7
- renders_many :items, "BetterUi::General::Accordion::ItemComponent"
8
-
9
- ACCORDION_THEME = {
10
- default: 'border-gray-200',
11
- white: 'border-gray-100 bg-white',
12
- blue: 'border-blue-200',
13
- red: 'border-red-200',
14
- green: 'border-green-200',
15
- yellow: 'border-yellow-200',
16
- violet: 'border-violet-200',
17
- orange: 'border-orange-200',
18
- rose: 'border-rose-200'
19
- }.freeze
20
-
21
- ACCORDION_VARIANT = {
22
- minimal: '',
23
- bordered: 'border rounded-lg',
24
- separated: 'space-y-2'
25
- }.freeze
26
-
27
- ACCORDION_SIZE = {
28
- small: 'text-sm',
29
- medium: 'text-base',
30
- large: 'text-lg'
31
- }.freeze
32
-
33
- def initialize(multiple: false, theme: :default, variant: :bordered, size: :medium,
34
- classes: '', **options)
35
- @multiple = multiple
36
- @theme = theme
37
- @variant = variant
38
- @size = size
39
- @classes = classes
40
- @options = options
41
-
42
- validate_params
43
- end
44
-
45
- private
46
-
47
- attr_reader :multiple, :theme, :variant, :size, :classes, :options
48
-
49
- def validate_params
50
- validate_theme
51
- validate_variant
52
- validate_size
53
- end
54
-
55
- def validate_theme
56
- return if ACCORDION_THEME.key?(theme)
57
-
58
- raise ArgumentError, "Invalid theme: #{theme}. Must be one of #{ACCORDION_THEME.keys}"
59
- end
60
-
61
- def validate_variant
62
- return if ACCORDION_VARIANT.key?(variant)
63
-
64
- raise ArgumentError, "Invalid variant: #{variant}. Must be one of #{ACCORDION_VARIANT.keys}"
65
- end
66
-
67
- def validate_size
68
- return if ACCORDION_SIZE.key?(size)
69
-
70
- raise ArgumentError, "Invalid size: #{size}. Must be one of #{ACCORDION_SIZE.keys}"
71
- end
72
-
73
- # Attributi per il wrapper principale
74
- def wrapper_attributes
75
- base_classes = [
76
- 'bui-accordion',
77
- ACCORDION_SIZE[size],
78
- ACCORDION_VARIANT[variant],
79
- ACCORDION_THEME[theme],
80
- classes
81
- ].compact.join(' ')
82
-
83
- {
84
- class: base_classes,
85
- 'data-controller': 'bui-accordion',
86
- 'data-bui-accordion-multiple-value': multiple
87
- }.merge(options)
88
- end
89
- end
90
- end
91
- end
92
- end
@@ -1,12 +0,0 @@
1
- <div <%= tag.attributes(item_attributes) %>>
2
- <!-- Header -->
3
- <button <%= tag.attributes(header_attributes) %>>
4
- <span><%= title %></span>
5
- <i class="fas fa-<%= icon %> <%= icon_attributes[:class] %>" <%= tag.attributes(icon_attributes.except(:class)) %>></i>
6
- </button>
7
-
8
- <!-- Content -->
9
- <div <%= tag.attributes(content_attributes) %>>
10
- <%= content %>
11
- </div>
12
- </div>