better_ui 0.3.0 → 0.6.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.
- checksums.yaml +4 -4
- data/app/components/better_ui/application/main/component.html.erb +1 -1
- data/app/components/better_ui/application/sidebar/component.html.erb +25 -3
- data/app/components/better_ui/application/sidebar/component.rb +62 -5
- data/app/components/better_ui/general/button/component.html.erb +8 -8
- data/app/components/better_ui/general/button/component.rb +11 -11
- data/app/components/better_ui/general/dropdown/component.html.erb +7 -4
- data/app/components/better_ui/general/dropdown/component.rb +23 -1
- data/app/components/better_ui/general/field/component.html.erb +3 -3
- data/app/components/better_ui/general/field/component.rb +3 -3
- data/app/components/better_ui/general/grid/cell_component.html.erb +3 -0
- data/app/components/better_ui/general/grid/cell_component.rb +390 -0
- data/app/components/better_ui/general/grid/component.html.erb +3 -0
- data/app/components/better_ui/general/grid/component.rb +301 -0
- data/app/components/better_ui/general/heading/component.html.erb +1 -1
- data/app/components/better_ui/general/icon/component.rb +2 -1
- data/app/components/better_ui/general/input/checkbox/component.rb +10 -10
- data/app/components/better_ui/general/input/pin/component.html.erb +1 -0
- data/app/components/better_ui/general/input/pin/component.rb +201 -0
- data/app/components/better_ui/general/input/radio/component.rb +10 -10
- data/app/components/better_ui/general/input/rating/component.html.erb +4 -0
- data/app/components/better_ui/general/input/rating/component.rb +272 -0
- data/app/components/better_ui/general/input/select/component.html.erb +76 -14
- data/app/components/better_ui/general/input/select/component.rb +166 -101
- data/app/components/better_ui/general/input/toggle/component.html.erb +5 -0
- data/app/components/better_ui/general/input/toggle/component.rb +242 -0
- data/app/components/better_ui/general/link/component.rb +1 -1
- data/app/components/better_ui/general/text/component.html.erb +1 -0
- data/app/components/better_ui/general/text/component.rb +194 -0
- data/app/helpers/better_ui/application_helper.rb +7 -0
- data/app/helpers/better_ui/general/components/button/button_helper.rb +6 -6
- data/app/helpers/better_ui/general/components/dropdown/dropdown_helper.rb +9 -0
- data/app/helpers/better_ui/general/components/dropdown/item_helper.rb +13 -7
- data/app/helpers/better_ui/general/components/field/field_helper.rb +4 -4
- data/app/helpers/better_ui/general/components/grid/grid_helper.rb +145 -0
- data/app/helpers/better_ui/general/components/input/pin/pin_helper.rb +76 -0
- data/app/helpers/better_ui/general/components/input/rating/rating_helper.rb +70 -0
- data/app/helpers/better_ui/general/components/input/select/select_helper.rb +47 -31
- data/app/helpers/better_ui/general/components/input/toggle/toggle_helper.rb +77 -0
- data/app/helpers/better_ui/general/components/text/text_helper.rb +83 -0
- data/lib/better_ui/version.rb +1 -1
- data/lib/better_ui.rb +1 -0
- metadata +19 -4
- data/app/helpers/better_ui/general/components/accordion.rb +0 -11
- data/app/helpers/better_ui/general/components/modal.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d5ce58a483a9db3c7164c77c50c5206f83304c2b52f6ebff2d92dbc2ddfe0c78
|
4
|
+
data.tar.gz: 262e9f1b61ccf46254e582c2466cf4fea4c89d6ec48cb1117cb63355996a3e2c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d024e430e9eb3d69c30adc09b8cff4a8a79a3585ea0769abe0e279c7dcb54b36faf7239ad393436f5558dc0db67c29a66e7eac8f32a11232d12cffbffc2cb96
|
7
|
+
data.tar.gz: 4c18bd0f1df604a289bab875eee931283616cd22f7b1a24e239446643392228a09b92f0e9b54888b9c3d8bdc2074a089ff0d35373aca0e60bccda86ef7b843fe
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<main class="w-full
|
1
|
+
<main class="w-full <%= get_layout_class %> <%= get_padding_class(padding) %><%= classes ? ' ' + classes : '' %>">
|
2
2
|
<div class="h-[calc(100vh-81px)] p-4">
|
3
3
|
<div class="h-full w-full bg-white p-4 <%= get_padding_class(inner_padding) %> <%= get_rounded_class %> <%= get_shadow_class %> overflow-y-auto">
|
4
4
|
<div class="h-full overflow-y-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]">
|
@@ -2,7 +2,8 @@
|
|
2
2
|
data-bui-sidebar-width-value="<%= @width == :md ? 256 : 320 %>"
|
3
3
|
data-bui-sidebar-min-width-value="200"
|
4
4
|
data-bui-sidebar-max-width-value="400"
|
5
|
-
data-bui-sidebar-pinned-value="true"
|
5
|
+
data-bui-sidebar-pinned-value="true"
|
6
|
+
class="<%= wrapper_classes %>">
|
6
7
|
|
7
8
|
<!-- Mobile Overlay -->
|
8
9
|
<div data-bui-sidebar-target="overlay" class="fixed inset-0 bg-black bg-opacity-50 z-40 hidden md:hidden"></div>
|
@@ -174,7 +175,28 @@
|
|
174
175
|
<!-- Footer Section -->
|
175
176
|
<% if has_footer? %>
|
176
177
|
<div class="px-6 py-4 border-t border-gray-200">
|
177
|
-
<% if
|
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? %>
|
178
200
|
<div class="flex items-center">
|
179
201
|
<% if footer[:user_info][:avatar].present? %>
|
180
202
|
<div class="flex-shrink-0">
|
@@ -206,7 +228,7 @@
|
|
206
228
|
<% end %>
|
207
229
|
|
208
230
|
<% if footer[:content].present? %>
|
209
|
-
<div class="<%= footer[:user_info].present? ? 'mt-4' : '' %>">
|
231
|
+
<div class="<%= (footer[:user_info].present? || has_user_dropdown?) ? 'mt-4' : '' %>">
|
210
232
|
<%= footer[:content] %>
|
211
233
|
</div>
|
212
234
|
<% end %>
|
@@ -4,10 +4,12 @@ module BetterUi
|
|
4
4
|
module Application
|
5
5
|
module Sidebar
|
6
6
|
class Component < ViewComponent::Base
|
7
|
-
# Include degli helper per utilizzare bui_icon, bui_avatar e
|
7
|
+
# Include degli helper per utilizzare bui_icon, bui_avatar, bui_button e bui_dropdown
|
8
8
|
include BetterUi::General::Components::Icon::IconHelper
|
9
9
|
include BetterUi::General::Components::Avatar::AvatarHelper
|
10
10
|
include BetterUi::General::Components::Button::ButtonHelper
|
11
|
+
include BetterUi::General::Components::Dropdown::DropdownHelper
|
12
|
+
include BetterUi::General::Components::Dropdown::ItemHelper
|
11
13
|
attr_reader :width, :position, :theme, :shadow, :border, :header, :footer, :navigation_sections, :collapsible, :classes
|
12
14
|
|
13
15
|
# Larghezze sidebar con classi Tailwind dirette
|
@@ -46,7 +48,7 @@ module BetterUi
|
|
46
48
|
# @param shadow [Symbol] Tipo di ombra (:none, :sm, :md, :lg), default :lg
|
47
49
|
# @param border [Boolean] Se mostrare il bordo destro/sinistro, default true
|
48
50
|
# @param header [Hash] Configurazione header (logo, title, subtitle)
|
49
|
-
# @param footer [Hash] Configurazione footer (content, user_info)
|
51
|
+
# @param footer [Hash] Configurazione footer (content, user_info, user_dropdown)
|
50
52
|
# @param navigation_sections [Array] Array di sezioni di navigazione
|
51
53
|
# @param collapsible [Boolean] Se abilitare sezioni collassabili, default true
|
52
54
|
# @param classes [String] Classi CSS aggiuntive
|
@@ -74,8 +76,8 @@ module BetterUi
|
|
74
76
|
@classes = classes
|
75
77
|
end
|
76
78
|
|
77
|
-
def
|
78
|
-
base_classes = %w[fixed inset-y-0 h-screen z-
|
79
|
+
def wrapper_classes
|
80
|
+
base_classes = %w[fixed top-0 inset-y-0 h-screen z-[9999]]
|
79
81
|
|
80
82
|
# Posizione
|
81
83
|
base_classes << (position == :right ? "right-0" : "left-0")
|
@@ -83,6 +85,12 @@ module BetterUi
|
|
83
85
|
# Larghezza
|
84
86
|
base_classes << width_class
|
85
87
|
|
88
|
+
base_classes.compact.join(" ")
|
89
|
+
end
|
90
|
+
|
91
|
+
def container_classes
|
92
|
+
base_classes = %w[flex flex-col h-full]
|
93
|
+
|
86
94
|
# Tema
|
87
95
|
base_classes.concat(theme_classes)
|
88
96
|
|
@@ -104,7 +112,56 @@ module BetterUi
|
|
104
112
|
end
|
105
113
|
|
106
114
|
def has_footer?
|
107
|
-
footer.present? && (footer[:content].present? || footer[:user_info].present?)
|
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
|
108
165
|
end
|
109
166
|
|
110
167
|
private
|
@@ -2,15 +2,15 @@
|
|
2
2
|
<% if link? %>
|
3
3
|
<%= link_to @href, **link_attributes do %>
|
4
4
|
<% if @icon && @icon_position == :left %>
|
5
|
-
<span class="flex-shrink-0<%= @
|
5
|
+
<span class="flex-shrink-0<%= @text.present? ? ' mr-2' : '' %>"><%= render_icon(@icon) %></span>
|
6
6
|
<% end %>
|
7
7
|
|
8
|
-
<% if @
|
9
|
-
<span class="flex-grow"><%= @
|
8
|
+
<% if @text %>
|
9
|
+
<span class="flex-grow"><%= @text %></span>
|
10
10
|
<% end %>
|
11
11
|
|
12
12
|
<% if @icon && @icon_position == :right %>
|
13
|
-
<span class="flex-shrink-0<%= @
|
13
|
+
<span class="flex-shrink-0<%= @text.present? ? ' ml-2' : '' %>"><%= render_icon(@icon) %></span>
|
14
14
|
<% end %>
|
15
15
|
|
16
16
|
<%= content %>
|
@@ -18,15 +18,15 @@
|
|
18
18
|
<% else %>
|
19
19
|
<%= tag.button(**button_attributes) do %>
|
20
20
|
<% if @icon && @icon_position == :left %>
|
21
|
-
<span class="flex-shrink-0<%= @
|
21
|
+
<span class="flex-shrink-0<%= @text.present? ? ' mr-2' : '' %>"><%= render_icon(@icon) %></span>
|
22
22
|
<% end %>
|
23
23
|
|
24
|
-
<% if @
|
25
|
-
<span class="flex-grow"><%= @
|
24
|
+
<% if @text %>
|
25
|
+
<span class="flex-grow"><%= @text %></span>
|
26
26
|
<% end %>
|
27
27
|
|
28
28
|
<% if @icon && @icon_position == :right %>
|
29
|
-
<span class="flex-shrink-0<%= @
|
29
|
+
<span class="flex-shrink-0<%= @text.present? ? ' ml-2' : '' %>"><%= render_icon(@icon) %></span>
|
30
30
|
<% end %>
|
31
31
|
|
32
32
|
<%= content %>
|
@@ -2,7 +2,7 @@ module BetterUi
|
|
2
2
|
module General
|
3
3
|
module Button
|
4
4
|
class Component < ViewComponent::Base
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :text, :theme, :size, :full_width, :disabled,
|
6
6
|
:icon, :icon_position, :href, :method, :data, :classes, :id, :rounded, :button_type, :html_options
|
7
7
|
|
8
8
|
# Classi base sempre presenti
|
@@ -40,8 +40,8 @@ module BetterUi
|
|
40
40
|
|
41
41
|
# Inizializzazione del componente
|
42
42
|
def initialize(
|
43
|
-
|
44
|
-
|
43
|
+
text: nil,
|
44
|
+
theme: :white,
|
45
45
|
size: :medium,
|
46
46
|
full_width: false,
|
47
47
|
disabled: false,
|
@@ -56,8 +56,8 @@ module BetterUi
|
|
56
56
|
button_type: :button,
|
57
57
|
**html_options
|
58
58
|
)
|
59
|
-
@
|
60
|
-
@
|
59
|
+
@text = text
|
60
|
+
@theme = theme.to_sym
|
61
61
|
@size = size.to_sym
|
62
62
|
@full_width = full_width
|
63
63
|
@disabled = disabled
|
@@ -95,7 +95,7 @@ module BetterUi
|
|
95
95
|
end
|
96
96
|
|
97
97
|
def get_button_type_classes
|
98
|
-
BUTTON_THEME[@
|
98
|
+
BUTTON_THEME[@theme] || BUTTON_THEME[:white]
|
99
99
|
end
|
100
100
|
|
101
101
|
def get_border_radius_class
|
@@ -173,21 +173,21 @@ module BetterUi
|
|
173
173
|
|
174
174
|
# Verifica se rendere il componente
|
175
175
|
def render?
|
176
|
-
@
|
176
|
+
@text.present? || @icon.present? || content.present?
|
177
177
|
end
|
178
178
|
|
179
179
|
private
|
180
180
|
|
181
181
|
def validate_params
|
182
|
-
|
182
|
+
validate_theme
|
183
183
|
validate_size
|
184
184
|
validate_icon_position
|
185
185
|
validate_rounded
|
186
186
|
end
|
187
187
|
|
188
|
-
def
|
189
|
-
unless BUTTON_THEME.keys.include?(@
|
190
|
-
raise ArgumentError, "Il
|
188
|
+
def validate_theme
|
189
|
+
unless BUTTON_THEME.keys.include?(@theme)
|
190
|
+
raise ArgumentError, "Il tema deve essere uno tra: #{BUTTON_THEME.keys.join(', ')}"
|
191
191
|
end
|
192
192
|
end
|
193
193
|
|
@@ -1,19 +1,22 @@
|
|
1
|
-
<div class="relative
|
1
|
+
<div class="relative <%= @classes %> <%= fullwidth_classes %>"
|
2
2
|
data-controller="bui-dropdown"
|
3
3
|
data-bui-dropdown-open-value="false"
|
4
|
+
data-bui-dropdown-selectable-value="<%= @selectable.to_s %>"
|
4
5
|
<%= tag.attributes(@html_options.except(:class)) %>>
|
5
6
|
|
6
7
|
<button type="button"
|
7
|
-
class="
|
8
|
+
class="items-center border font-medium focus:outline-none focus:ring-2 focus:ring-offset-2 transition-colors <%= dynamic_trigger_classes %> <%= fullwidth_classes %>"
|
8
9
|
data-bui-dropdown-target="trigger"
|
9
10
|
data-action="click->bui-dropdown#toggle keydown->bui-dropdown#keydown"
|
10
11
|
aria-expanded="false"
|
11
12
|
aria-haspopup="true">
|
12
13
|
<%= @trigger %>
|
13
|
-
|
14
|
+
<% if @show_chevron %>
|
15
|
+
<%= bui_icon("chevron-down", size: :small, classes: "ml-2 -mr-1") %>
|
16
|
+
<% end %>
|
14
17
|
</button>
|
15
18
|
|
16
|
-
<div class="absolute z-
|
19
|
+
<div class="absolute z-[1000] my-2 origin-top-right bg-white border border-gray-200 shadow-lg focus:outline-none <%= dynamic_menu_classes %> <%= fullwidth_classes %>"
|
17
20
|
data-bui-dropdown-target="menu"
|
18
21
|
role="menu"
|
19
22
|
aria-orientation="vertical"
|
@@ -6,7 +6,7 @@ module BetterUi
|
|
6
6
|
class Component < ViewComponent::Base
|
7
7
|
include BetterUi::General::Components::Icon::IconHelper
|
8
8
|
|
9
|
-
attr_reader :trigger, :position, :theme, :size, :rounded, :animation, :classes, :html_options
|
9
|
+
attr_reader :trigger, :position, :theme, :size, :rounded, :animation, :fullwidth, :show_chevron, :selectable, :classes, :html_options
|
10
10
|
|
11
11
|
# Classi base spostate nel template HTML per migliore leggibilità
|
12
12
|
|
@@ -54,6 +54,12 @@ module BetterUi
|
|
54
54
|
none: ""
|
55
55
|
}.freeze
|
56
56
|
|
57
|
+
# Stili per full-width del trigger
|
58
|
+
DROPDOWN_FULLWIDTH = {
|
59
|
+
true => "w-full text-left justify-start",
|
60
|
+
false => "inline-flex justify-center"
|
61
|
+
}.freeze
|
62
|
+
|
57
63
|
def initialize(
|
58
64
|
trigger:,
|
59
65
|
position: :bottom,
|
@@ -61,6 +67,9 @@ module BetterUi
|
|
61
67
|
size: :medium,
|
62
68
|
rounded: :medium,
|
63
69
|
animation: :fade,
|
70
|
+
fullwidth: false,
|
71
|
+
show_chevron: true,
|
72
|
+
selectable: false,
|
64
73
|
classes: nil,
|
65
74
|
**html_options
|
66
75
|
)
|
@@ -70,12 +79,21 @@ module BetterUi
|
|
70
79
|
@size = size.to_sym
|
71
80
|
@rounded = rounded.to_sym
|
72
81
|
@animation = animation.to_sym
|
82
|
+
@fullwidth = fullwidth
|
83
|
+
@show_chevron = show_chevron
|
84
|
+
@selectable = selectable
|
73
85
|
@classes = classes
|
74
86
|
@html_options = html_options
|
75
87
|
|
76
88
|
validate_params
|
77
89
|
end
|
78
90
|
|
91
|
+
def fullwidth_classes
|
92
|
+
[
|
93
|
+
get_fullwidth_classes
|
94
|
+
].compact.join(" ")
|
95
|
+
end
|
96
|
+
|
79
97
|
# Restituisce solo le classi dinamiche per il trigger
|
80
98
|
def dynamic_trigger_classes
|
81
99
|
[
|
@@ -127,6 +145,10 @@ module BetterUi
|
|
127
145
|
DROPDOWN_ANIMATION[@animation] || DROPDOWN_ANIMATION[:fade]
|
128
146
|
end
|
129
147
|
|
148
|
+
def get_fullwidth_classes
|
149
|
+
DROPDOWN_FULLWIDTH[@fullwidth] || DROPDOWN_FULLWIDTH[false]
|
150
|
+
end
|
151
|
+
|
130
152
|
def validate_params
|
131
153
|
validate_theme
|
132
154
|
validate_size
|
@@ -1,8 +1,8 @@
|
|
1
1
|
<%# Form field component template %>
|
2
2
|
<div class="<%= BASE_CLASSES %>">
|
3
|
-
<% if
|
3
|
+
<% if text.present? %>
|
4
4
|
<label for="<%= id %>" class="<%= LABEL_CLASSES %>">
|
5
|
-
<%=
|
5
|
+
<%= text %>
|
6
6
|
<% if required %>
|
7
7
|
<span class="<%= REQUIRED_CLASSES %>">*</span>
|
8
8
|
<% end %>
|
@@ -24,4 +24,4 @@
|
|
24
24
|
<%= help_text %>
|
25
25
|
</div>
|
26
26
|
<% end %>
|
27
|
-
</div>
|
27
|
+
</div>
|
@@ -4,7 +4,7 @@ module BetterUi
|
|
4
4
|
module General
|
5
5
|
module Field
|
6
6
|
class Component < ViewComponent::Base
|
7
|
-
attr_reader :
|
7
|
+
attr_reader :text, :name, :required, :error, :help_text, :id
|
8
8
|
|
9
9
|
renders_one :input
|
10
10
|
|
@@ -14,8 +14,8 @@ module BetterUi
|
|
14
14
|
ERROR_CLASSES = "text-sm text-red-600 mt-1"
|
15
15
|
HELP_TEXT_CLASSES = "text-sm text-gray-500 mt-1"
|
16
16
|
|
17
|
-
def initialize(
|
18
|
-
@
|
17
|
+
def initialize(text:, name:, required: false, error: nil, help_text: nil, id: nil)
|
18
|
+
@text = text
|
19
19
|
@name = name
|
20
20
|
@required = required
|
21
21
|
@error = error
|