better_ui 0.1.0 → 0.5.0

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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +199 -75
  3. data/app/assets/javascripts/better_ui/controllers/navbar_controller.js +138 -0
  4. data/app/assets/javascripts/better_ui/controllers/sidebar_controller.js +211 -0
  5. data/app/assets/javascripts/better_ui/controllers/toast_controller.js +161 -0
  6. data/app/assets/javascripts/better_ui/index.js +159 -0
  7. data/app/assets/javascripts/better_ui/toast_manager.js +77 -0
  8. data/app/assets/stylesheets/better_ui/application.css +25 -351
  9. data/app/components/better_ui/application/alert_component.html.erb +27 -0
  10. data/app/components/better_ui/application/alert_component.rb +202 -0
  11. data/app/components/better_ui/application/card_component.html.erb +24 -0
  12. data/app/components/better_ui/application/card_component.rb +53 -0
  13. data/app/components/better_ui/application/card_container_component.html.erb +8 -0
  14. data/app/components/better_ui/application/card_container_component.rb +14 -0
  15. data/app/components/better_ui/application/header_component.html.erb +88 -0
  16. data/app/components/better_ui/application/header_component.rb +188 -0
  17. data/app/components/better_ui/application/navbar_component.html.erb +294 -0
  18. data/app/components/better_ui/application/navbar_component.rb +249 -0
  19. data/app/components/better_ui/application/sidebar_component.html.erb +207 -0
  20. data/app/components/better_ui/application/sidebar_component.rb +318 -0
  21. data/app/components/better_ui/application/toast_component.html.erb +35 -0
  22. data/app/components/better_ui/application/toast_component.rb +223 -0
  23. data/app/components/better_ui/general/avatar_component.html.erb +19 -0
  24. data/app/components/better_ui/general/avatar_component.rb +171 -0
  25. data/app/components/better_ui/general/badge_component.html.erb +19 -0
  26. data/app/components/better_ui/general/badge_component.rb +123 -0
  27. data/app/components/better_ui/general/breadcrumb_component.html.erb +15 -0
  28. data/app/components/better_ui/general/breadcrumb_component.rb +130 -0
  29. data/app/components/better_ui/general/button_component.html.erb +34 -0
  30. data/app/components/better_ui/general/button_component.rb +162 -0
  31. data/app/components/better_ui/general/heading_component.html.erb +25 -0
  32. data/app/components/better_ui/general/heading_component.rb +148 -0
  33. data/app/components/better_ui/general/icon_component.html.erb +2 -0
  34. data/app/components/better_ui/general/icon_component.rb +100 -0
  35. data/app/components/better_ui/general/link_component.html.erb +17 -0
  36. data/app/components/better_ui/general/link_component.rb +132 -0
  37. data/app/components/better_ui/general/panel_component.html.erb +27 -0
  38. data/app/components/better_ui/general/panel_component.rb +103 -0
  39. data/app/components/better_ui/general/spinner_component.html.erb +15 -0
  40. data/app/components/better_ui/general/spinner_component.rb +79 -0
  41. data/app/components/better_ui/general/table_component.html.erb +73 -0
  42. data/app/components/better_ui/general/table_component.rb +167 -0
  43. data/app/components/better_ui/theme_helper.rb +171 -0
  44. data/app/controllers/better_ui/application_controller.rb +1 -0
  45. data/app/controllers/better_ui/docs_controller.rb +18 -25
  46. data/app/views/components/better_ui/general/table/_custom_body_row.html.erb +17 -0
  47. data/app/views/components/better_ui/general/table/_custom_footer_rows.html.erb +17 -0
  48. data/app/views/components/better_ui/general/table/_custom_header_rows.html.erb +12 -0
  49. data/app/views/layouts/component_preview.html.erb +32 -0
  50. data/config/initializers/lookbook.rb +23 -0
  51. data/config/routes.rb +6 -1
  52. data/lib/better_ui/engine.rb +18 -1
  53. data/lib/better_ui/version.rb +1 -1
  54. data/lib/better_ui.rb +4 -0
  55. data/lib/generators/better_ui/stylesheet_generator.rb +96 -0
  56. data/lib/generators/better_ui/templates/README +56 -0
  57. data/lib/generators/better_ui/templates/components/_avatar.scss +151 -0
  58. data/lib/generators/better_ui/templates/components/_badge.scss +142 -0
  59. data/lib/generators/better_ui/templates/components/_breadcrumb.scss +107 -0
  60. data/lib/generators/better_ui/templates/components/_button.scss +106 -0
  61. data/lib/generators/better_ui/templates/components/_card.scss +69 -0
  62. data/lib/generators/better_ui/templates/components/_heading.scss +180 -0
  63. data/lib/generators/better_ui/templates/components/_icon.scss +90 -0
  64. data/lib/generators/better_ui/templates/components/_link.scss +130 -0
  65. data/lib/generators/better_ui/templates/components/_panel.scss +144 -0
  66. data/lib/generators/better_ui/templates/components/_spinner.scss +132 -0
  67. data/lib/generators/better_ui/templates/components/_table.scss +105 -0
  68. data/lib/generators/better_ui/templates/components/_variables.scss +33 -0
  69. data/lib/generators/better_ui/templates/components_stylesheet.scss +66 -0
  70. metadata +135 -10
  71. data/app/helpers/better_ui/application_helper.rb +0 -183
  72. data/app/views/better_ui/docs/component.html.erb +0 -365
  73. data/app/views/better_ui/docs/index.html.erb +0 -100
  74. data/app/views/better_ui/docs/show.html.erb +0 -60
  75. data/app/views/layouts/better_ui/application.html.erb +0 -135
@@ -0,0 +1,171 @@
1
+ module BetterUi
2
+ module General
3
+ class AvatarComponent < ViewComponent::Base
4
+ attr_reader :name, :src, :size, :shape, :status, :status_position, :type, :classes, :id
5
+
6
+ # Temi di colore disponibili
7
+ AVATAR_THEME = {
8
+ default: "bui-avatar-default",
9
+ white: "bui-avatar-white",
10
+ red: "bui-avatar-red",
11
+ rose: "bui-avatar-rose",
12
+ orange: "bui-avatar-orange",
13
+ green: "bui-avatar-green",
14
+ blue: "bui-avatar-blue",
15
+ yellow: "bui-avatar-yellow",
16
+ violet: "bui-avatar-violet",
17
+ gray: "bui-avatar-gray"
18
+ }
19
+
20
+ # Dimensioni disponibili
21
+ AVATAR_SIZES = {
22
+ xxsmall: "bui-avatar-size-xxsmall",
23
+ xsmall: "bui-avatar-size-xsmall",
24
+ small: "bui-avatar-size-small",
25
+ medium: "bui-avatar-size-medium",
26
+ large: "bui-avatar-size-large",
27
+ xlarge: "bui-avatar-size-xlarge",
28
+ xxlarge: "bui-avatar-size-xxlarge"
29
+ }
30
+
31
+ # Forme disponibili
32
+ AVATAR_SHAPES = {
33
+ circle: "bui-avatar-shape-circle",
34
+ square: "bui-avatar-shape-square",
35
+ rounded: "bui-avatar-shape-rounded"
36
+ }
37
+
38
+ # Stati online disponibili
39
+ AVATAR_STATUS = {
40
+ online: "bui-avatar-status-online",
41
+ offline: "bui-avatar-status-offline",
42
+ busy: "bui-avatar-status-busy",
43
+ away: "bui-avatar-status-away"
44
+ }
45
+
46
+ # Posizioni dell'indicatore di stato
47
+ AVATAR_STATUS_POSITION = {
48
+ bottom_right: "bui-avatar-status-position-bottom-right",
49
+ bottom_left: "bui-avatar-status-position-bottom-left",
50
+ top_right: "bui-avatar-status-position-top-right",
51
+ top_left: "bui-avatar-status-position-top-left"
52
+ }
53
+
54
+ def initialize(
55
+ name: nil,
56
+ src: nil,
57
+ size: :medium,
58
+ shape: :circle,
59
+ status: nil,
60
+ status_position: :bottom_right,
61
+ type: :default,
62
+ classes: nil,
63
+ id: nil
64
+ )
65
+ @name = name
66
+ @src = src
67
+ @size = size.to_sym
68
+ @shape = shape.to_sym
69
+ @status = status&.to_sym
70
+ @status_position = status_position.to_sym
71
+ @type = type.to_sym
72
+ @classes = classes
73
+ @id = id
74
+ end
75
+
76
+ # Combina tutte le classi
77
+ def combined_classes
78
+ [
79
+ "bui-avatar", # Classe base per tutti gli avatar
80
+ get_avatar_theme_class,
81
+ get_avatar_size_class,
82
+ get_avatar_shape_class,
83
+ @classes
84
+ ].compact.join(" ")
85
+ end
86
+
87
+ def get_avatar_theme_class
88
+ AVATAR_THEME[@type] || AVATAR_THEME[:default]
89
+ end
90
+
91
+ def get_avatar_size_class
92
+ AVATAR_SIZES[@size] || AVATAR_SIZES[:medium]
93
+ end
94
+
95
+ def get_avatar_shape_class
96
+ AVATAR_SHAPES[@shape] || AVATAR_SHAPES[:circle]
97
+ end
98
+
99
+ def get_avatar_status_class
100
+ AVATAR_STATUS[@status] || ""
101
+ end
102
+
103
+ def get_avatar_status_position_class
104
+ AVATAR_STATUS_POSITION[@status_position] || AVATAR_STATUS_POSITION[:bottom_right]
105
+ end
106
+
107
+ # Restituisce gli attributi per l'avatar
108
+ def avatar_attributes
109
+ attrs = {
110
+ class: combined_classes,
111
+ id: @id
112
+ }
113
+
114
+ attrs
115
+ end
116
+
117
+ # Restituisce le classi per l'indicatore di stato
118
+ def status_indicator_classes
119
+ [
120
+ "bui-avatar-status-indicator",
121
+ get_avatar_status_class,
122
+ get_avatar_status_position_class
123
+ ].compact.join(" ")
124
+ end
125
+
126
+ # Determina se mostrare l'indicatore di stato
127
+ def show_status?
128
+ @status.present? && AVATAR_STATUS.key?(@status)
129
+ end
130
+
131
+ # Ottiene le iniziali dal nome
132
+ def initials
133
+ return "" unless @name.present?
134
+
135
+ words = @name.strip.split(/\s+/)
136
+ if words.size >= 2
137
+ "#{words[0][0]}#{words[1][0]}".upcase
138
+ else
139
+ @name[0..1].upcase
140
+ end
141
+ end
142
+
143
+ # Determina se mostrare l'immagine
144
+ def show_image?
145
+ @src.present?
146
+ end
147
+
148
+ # Ottiene le dimensioni dell'avatar in pixel
149
+ def pixel_size
150
+ case @size
151
+ when :xxsmall
152
+ 20
153
+ when :xsmall
154
+ 24
155
+ when :small
156
+ 32
157
+ when :medium
158
+ 40
159
+ when :large
160
+ 48
161
+ when :xlarge
162
+ 64
163
+ when :xxlarge
164
+ 96
165
+ else
166
+ 40
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,19 @@
1
+ <span <%= badge_attributes.to_s.html_safe %>>
2
+ <% if @icon && @icon_position == :left %>
3
+ <span class="bui-badge-icon-left">
4
+ <%= render_icon(@icon) %>
5
+ </span>
6
+ <% end %>
7
+
8
+ <% if @label.present? %>
9
+ <span class="bui-badge-label"><%= @label %></span>
10
+ <% end %>
11
+
12
+ <% if @icon && @icon_position == :right %>
13
+ <span class="bui-badge-icon-right">
14
+ <%= render_icon(@icon) %>
15
+ </span>
16
+ <% end %>
17
+
18
+ <%= content %>
19
+ </span>
@@ -0,0 +1,123 @@
1
+ module BetterUi
2
+ module General
3
+ class BadgeComponent < ViewComponent::Base
4
+ attr_reader :label, :type, :size, :icon, :icon_position, :rounded, :notification, :outline, :classes, :id
5
+
6
+ # Temi di colore disponibili
7
+ BADGE_THEME = {
8
+ default: "bui-badge-default",
9
+ white: "bui-badge-white",
10
+ red: "bui-badge-red",
11
+ rose: "bui-badge-rose",
12
+ orange: "bui-badge-orange",
13
+ green: "bui-badge-green",
14
+ blue: "bui-badge-blue",
15
+ yellow: "bui-badge-yellow",
16
+ violet: "bui-badge-violet",
17
+ gray: "bui-badge-gray"
18
+ }
19
+
20
+ # Dimensioni disponibili
21
+ BADGE_SIZES = {
22
+ small: "bui-badge-size-small",
23
+ medium: "bui-badge-size-medium",
24
+ large: "bui-badge-size-large"
25
+ }
26
+
27
+ # Border radius disponibili
28
+ BADGE_RADIUS = {
29
+ none: "bui-badge-radius-none",
30
+ small: "bui-badge-radius-small",
31
+ medium: "bui-badge-radius-medium",
32
+ large: "bui-badge-radius-large",
33
+ full: "bui-badge-radius-full"
34
+ }
35
+
36
+ # Stati e varianti
37
+ BADGE_VARIANTS = {
38
+ outline: "bui-badge-outline",
39
+ notification: "bui-badge-notification"
40
+ }
41
+
42
+ # Inizializzazione del componente
43
+ def initialize(
44
+ label: nil,
45
+ type: :default,
46
+ size: :medium,
47
+ icon: nil,
48
+ icon_position: :left,
49
+ rounded: :medium,
50
+ notification: false,
51
+ outline: false,
52
+ classes: nil,
53
+ id: nil
54
+ )
55
+ @label = label
56
+ @type = type.to_sym
57
+ @size = size.to_sym
58
+ @icon = icon
59
+ @icon_position = icon_position.to_sym
60
+ @rounded = rounded.to_sym
61
+ @notification = notification
62
+ @outline = outline
63
+ @classes = classes
64
+ @id = id
65
+ end
66
+
67
+ # Combina tutte le classi
68
+ def combined_classes
69
+ [
70
+ "bui-badge", # Classe base per tutti i badge
71
+ get_badge_type_class,
72
+ get_badge_size_class,
73
+ get_border_radius_class,
74
+ @outline ? BADGE_VARIANTS[:outline] : "",
75
+ @notification ? BADGE_VARIANTS[:notification] : "",
76
+ @classes
77
+ ].compact.join(" ")
78
+ end
79
+
80
+ def get_badge_type_class
81
+ BADGE_THEME[@type] || BADGE_THEME[:default]
82
+ end
83
+
84
+ def get_badge_size_class
85
+ BADGE_SIZES[@size] || BADGE_SIZES[:medium]
86
+ end
87
+
88
+ def get_border_radius_class
89
+ BADGE_RADIUS[@rounded] || BADGE_RADIUS[:medium]
90
+ end
91
+
92
+ # Restituisce gli attributi per il badge
93
+ def badge_attributes
94
+ attrs = {
95
+ class: combined_classes,
96
+ id: @id
97
+ }
98
+
99
+ attrs
100
+ end
101
+
102
+ # Helper per renderizzare le icone
103
+ def render_icon(icon_name)
104
+ # Mappa le dimensioni del badge alle dimensioni dell'icona
105
+ icon_size = case @size
106
+ when :large
107
+ :small
108
+ when :small
109
+ :tiny
110
+ else
111
+ :tiny
112
+ end
113
+
114
+ # Utilizziamo il componente Icon
115
+ render BetterUi::General::IconComponent.new(
116
+ name: icon_name,
117
+ size: icon_size,
118
+ fixed_width: true
119
+ )
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,15 @@
1
+ <nav aria-label="Breadcrumb" class="<%= container_classes %>">
2
+ <ol class="bui-breadcrumb-list">
3
+ <% @items.each_with_index do |item, index| %>
4
+ <li class="bui-breadcrumb-item">
5
+ <%= render link_for_item(item, active: last_item?(index)) %>
6
+
7
+ <% unless last_item?(index) %>
8
+ <span class="<%= separator_classes %>" aria-hidden="true">
9
+ <%= separator_text %>
10
+ </span>
11
+ <% end %>
12
+ </li>
13
+ <% end %>
14
+ </ol>
15
+ </nav>
@@ -0,0 +1,130 @@
1
+ module BetterUi
2
+ module General
3
+ class BreadcrumbComponent < ViewComponent::Base
4
+ attr_reader :items, :separator, :size, :theme, :classes
5
+
6
+ # Temi di colore disponibili
7
+ BREADCRUMB_THEME = {
8
+ default: {
9
+ container: "bui-breadcrumb-default-container",
10
+ separator: "bui-breadcrumb-default-separator"
11
+ },
12
+ white: {
13
+ container: "bui-breadcrumb-white-container",
14
+ separator: "bui-breadcrumb-white-separator"
15
+ },
16
+ red: {
17
+ container: "bui-breadcrumb-red-container",
18
+ separator: "bui-breadcrumb-red-separator"
19
+ },
20
+ rose: {
21
+ container: "bui-breadcrumb-rose-container",
22
+ separator: "bui-breadcrumb-rose-separator"
23
+ },
24
+ orange: {
25
+ container: "bui-breadcrumb-orange-container",
26
+ separator: "bui-breadcrumb-orange-separator"
27
+ },
28
+ green: {
29
+ container: "bui-breadcrumb-green-container",
30
+ separator: "bui-breadcrumb-green-separator"
31
+ },
32
+ blue: {
33
+ container: "bui-breadcrumb-blue-container",
34
+ separator: "bui-breadcrumb-blue-separator"
35
+ },
36
+ yellow: {
37
+ container: "bui-breadcrumb-yellow-container",
38
+ separator: "bui-breadcrumb-yellow-separator"
39
+ },
40
+ violet: {
41
+ container: "bui-breadcrumb-violet-container",
42
+ separator: "bui-breadcrumb-violet-separator"
43
+ }
44
+ }
45
+
46
+ # Dimensioni disponibili
47
+ BREADCRUMB_SIZES = {
48
+ small: "bui-breadcrumb-small",
49
+ medium: "bui-breadcrumb-medium",
50
+ large: "bui-breadcrumb-large"
51
+ }
52
+
53
+ # Separatori predefiniti
54
+ BREADCRUMB_SEPARATORS = {
55
+ slash: "/",
56
+ chevron: "›",
57
+ arrow: "→",
58
+ dot: "•",
59
+ pipe: "|"
60
+ }
61
+
62
+ # Inizializzazione del componente
63
+ def initialize(
64
+ items: [],
65
+ separator: :chevron,
66
+ size: :medium,
67
+ theme: :default,
68
+ classes: nil
69
+ )
70
+ @items = items || []
71
+ @separator = separator.to_sym
72
+ @size = size.to_sym
73
+ @theme = theme.to_sym
74
+ @classes = classes
75
+ end
76
+
77
+ # Restituisce il separatore come stringa
78
+ def separator_text
79
+ if BREADCRUMB_SEPARATORS.key?(@separator)
80
+ BREADCRUMB_SEPARATORS[@separator]
81
+ else
82
+ @separator.to_s
83
+ end
84
+ end
85
+
86
+ # Genera le classi per il container
87
+ def container_classes
88
+ [
89
+ "bui-breadcrumb-container",
90
+ BREADCRUMB_SIZES.fetch(@size, BREADCRUMB_SIZES[:medium]),
91
+ BREADCRUMB_THEME.fetch(@theme, BREADCRUMB_THEME[:default])[:container],
92
+ @classes
93
+ ].compact.join(" ")
94
+ end
95
+
96
+ # Genera le classi per il separatore
97
+ def separator_classes
98
+ [
99
+ "bui-breadcrumb-separator",
100
+ BREADCRUMB_THEME.fetch(@theme, BREADCRUMB_THEME[:default])[:separator]
101
+ ].compact.join(" ")
102
+ end
103
+
104
+ # Verifica se un item è l'ultimo (attivo)
105
+ def last_item?(index)
106
+ index == @items.length - 1
107
+ end
108
+
109
+ # Crea un componente link per l'item
110
+ def link_for_item(item, active: false)
111
+ label = item.is_a?(Hash) ? item[:label] : item.to_s
112
+ href = item.is_a?(Hash) ? item[:url] : nil
113
+ icon = item.is_a?(Hash) ? item[:icon] : nil
114
+
115
+ BetterUi::General::LinkComponent.new(
116
+ label: label,
117
+ href: href,
118
+ theme: @theme,
119
+ icon: icon,
120
+ active: active
121
+ )
122
+ end
123
+
124
+ # Verifica se rendere il componente
125
+ def render?
126
+ @items.present? && @items.length > 0
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,34 @@
1
+ <%# Template per il bottone %>
2
+ <% if link? %>
3
+ <%= link_to @href, **link_attributes do %>
4
+ <% if @icon && @icon_position == :left %>
5
+ <span class="bui-btn-icon-left"><%= render_icon(@icon) %></span>
6
+ <% end %>
7
+
8
+ <% if @label %>
9
+ <span><%= @label %></span>
10
+ <% end %>
11
+
12
+ <% if @icon && @icon_position == :right %>
13
+ <span class="bui-btn-icon-right"><%= render_icon(@icon) %></span>
14
+ <% end %>
15
+
16
+ <%= content %>
17
+ <% end %>
18
+ <% else %>
19
+ <%= tag.button(**button_attributes) do %>
20
+ <% if @icon && @icon_position == :left %>
21
+ <span class="bui-btn-icon-left"><%= render_icon(@icon) %></span>
22
+ <% end %>
23
+
24
+ <% if @label %>
25
+ <span><%= @label %></span>
26
+ <% end %>
27
+
28
+ <% if @icon && @icon_position == :right %>
29
+ <span class="bui-btn-icon-right"><%= render_icon(@icon) %></span>
30
+ <% end %>
31
+
32
+ <%= content %>
33
+ <% end %>
34
+ <% end %>
@@ -0,0 +1,162 @@
1
+ module BetterUi
2
+ module General
3
+ class ButtonComponent < ViewComponent::Base
4
+ attr_reader :label, :type, :size, :full_width, :disabled,
5
+ :icon, :icon_position, :href, :method, :data, :classes, :id, :rounded
6
+
7
+ # Temi di bottoni disponibili con classi CSS personalizzate
8
+ BUTTON_THEME = {
9
+ default: "bui-btn-default",
10
+ white: "bui-btn-white",
11
+ red: "bui-btn-red",
12
+ rose: "bui-btn-rose",
13
+ orange: "bui-btn-orange",
14
+ green: "bui-btn-green",
15
+ blue: "bui-btn-blue",
16
+ yellow: "bui-btn-yellow",
17
+ violet: "bui-btn-violet"
18
+ }
19
+
20
+ # Dimensioni disponibili con classi CSS personalizzate
21
+ BUTTON_SIZES = {
22
+ small: "bui-btn-size-small",
23
+ medium: "bui-btn-size-medium",
24
+ large: "bui-btn-size-large"
25
+ }
26
+
27
+ # Border radius disponibili con classi CSS personalizzate
28
+ BUTTON_RADIUS = {
29
+ none: "bui-btn-radius-none",
30
+ small: "bui-btn-radius-small",
31
+ medium: "bui-btn-radius-medium",
32
+ large: "bui-btn-radius-large",
33
+ full: "bui-btn-radius-full"
34
+ }
35
+
36
+ # Stati e comportamenti del bottone
37
+ BUTTON_STATES = {
38
+ disabled: "bui-btn-disabled",
39
+ full_width: "bui-btn-full-width"
40
+ }
41
+
42
+ # Layout e stili comuni
43
+ BUTTON_LAYOUT = {
44
+ default: "bui-btn-layout-default",
45
+ focus: "bui-btn-focus"
46
+ }
47
+
48
+ # Inizializzazione del componente
49
+ def initialize(
50
+ label: nil,
51
+ type: :default,
52
+ size: :medium,
53
+ full_width: false,
54
+ disabled: false,
55
+ icon: nil,
56
+ icon_position: :left,
57
+ href: nil,
58
+ method: nil,
59
+ data: {},
60
+ classes: nil,
61
+ id: nil,
62
+ rounded: :small
63
+ )
64
+ @label = label
65
+ @type = type.to_sym
66
+ @size = size.to_sym
67
+ @full_width = full_width
68
+ @disabled = disabled
69
+ @icon = icon
70
+ @icon_position = icon_position.to_sym
71
+ @href = href
72
+ @method = method
73
+ @data = data
74
+ @classes = classes
75
+ @id = id
76
+ @rounded = rounded.to_sym
77
+ end
78
+
79
+ # Determina se il bottone è un link o un button
80
+ def link?
81
+ @href.present?
82
+ end
83
+
84
+ # Combina tutte le classi
85
+ def combined_classes
86
+ [
87
+ "bui-btn", # Classe base per tutti i bottoni
88
+ BUTTON_LAYOUT[:default],
89
+ BUTTON_LAYOUT[:focus],
90
+ get_border_radius_class,
91
+ get_button_type_classes,
92
+ get_button_size_classes,
93
+ @full_width ? BUTTON_STATES[:full_width] : "",
94
+ @disabled ? BUTTON_STATES[:disabled] : "",
95
+ @classes
96
+ ].compact.join(" ")
97
+ end
98
+
99
+ def get_button_type_classes
100
+ BUTTON_THEME[@type] || BUTTON_THEME[:default]
101
+ end
102
+
103
+ def get_border_radius_class
104
+ BUTTON_RADIUS[@rounded] || BUTTON_RADIUS[:small]
105
+ end
106
+
107
+ def get_button_size_classes
108
+ BUTTON_SIZES[@size] || BUTTON_SIZES[:medium]
109
+ end
110
+
111
+ # Restituisce gli attributi per il bottone
112
+ def button_attributes
113
+ attrs = {
114
+ class: combined_classes,
115
+ type: "button",
116
+ id: @id
117
+ }
118
+
119
+ attrs[:disabled] = true if @disabled
120
+ attrs[:data] = @data if @data.present?
121
+ attrs
122
+ end
123
+
124
+ # Restituisce gli attributi per il link
125
+ def link_attributes
126
+ attrs = {
127
+ class: combined_classes,
128
+ id: @id
129
+ }
130
+
131
+ attrs[:data] = @data.merge(turbo_method: @method) if @method.present?
132
+ attrs[:data] = @data if @data.present? && !@method.present?
133
+ attrs[:href] = @disabled ? nil : @href
134
+ attrs[:role] = "button"
135
+ attrs[:tabindex] = @disabled ? "-1" : "0"
136
+ attrs[:aria] = { disabled: @disabled } if @disabled
137
+
138
+ attrs
139
+ end
140
+
141
+ # Helper per renderizzare le icone
142
+ def render_icon(icon_name)
143
+ # Mappa le dimensioni del bottone alle dimensioni dell'icona
144
+ icon_size = case @size
145
+ when :large
146
+ :large
147
+ when :small
148
+ :small
149
+ else
150
+ :medium
151
+ end
152
+
153
+ # Utilizziamo il componente Icon
154
+ render BetterUi::General::IconComponent.new(
155
+ name: icon_name,
156
+ size: icon_size,
157
+ fixed_width: true
158
+ )
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,25 @@
1
+ <div class="<%= container_classes %>">
2
+ <%# Utilizzo di tag heading dinamico in base al livello specificato %>
3
+ <<%= "h#{@level}" %> class="<%= heading_classes %>">
4
+ <% if @icon.present? %>
5
+ <span class="bui-header-icon-container">
6
+ <span class="bui-header-icon-wrapper">
7
+ <%= render BetterUi::General::IconComponent.new(name: @icon, size: get_icon_size) %>
8
+ </span>
9
+ <%= @text || content %>
10
+ </span>
11
+ <% else %>
12
+ <%= @text || content %>
13
+ <% end %>
14
+ </<%= "h#{@level}" %>>
15
+
16
+ <% if @subtitle.present? %>
17
+ <div class="<%= subtitle_classes %>">
18
+ <%= @subtitle %>
19
+ </div>
20
+ <% end %>
21
+
22
+ <% if @with_divider %>
23
+ <div class="<%= divider_classes %>"></div>
24
+ <% end %>
25
+ </div>