better_ui 0.6.0 → 0.7.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/README.md +257 -212
- data/Rakefile +11 -2
- data/app/components/better_ui/action_messages_component/action_messages_component.html.erb +48 -0
- data/app/components/better_ui/action_messages_component.rb +544 -0
- data/app/components/better_ui/application_component.rb +66 -0
- data/app/components/better_ui/button_component/button_component.html.erb +31 -0
- data/app/components/better_ui/button_component.rb +307 -0
- data/app/components/better_ui/card_component/card_component.html.erb +17 -0
- data/app/components/better_ui/card_component.rb +460 -0
- data/app/components/better_ui/drawer/header_component/header_component.html.erb +24 -0
- data/app/components/better_ui/drawer/header_component.rb +238 -0
- data/app/components/better_ui/drawer/layout_component/layout_component.html.erb +44 -0
- data/app/components/better_ui/drawer/layout_component.rb +270 -0
- data/app/components/better_ui/drawer/nav_group_component/nav_group_component.html.erb +10 -0
- data/app/components/better_ui/drawer/nav_group_component.rb +155 -0
- data/app/components/better_ui/drawer/nav_item_component/nav_item_component.html.erb +13 -0
- data/app/components/better_ui/drawer/nav_item_component.rb +225 -0
- data/app/components/better_ui/drawer/sidebar_component/sidebar_component.html.erb +17 -0
- data/app/components/better_ui/drawer/sidebar_component.rb +263 -0
- data/app/components/better_ui/forms/base_component.rb +450 -0
- data/app/components/better_ui/forms/checkbox_component/checkbox_component.html.erb +28 -0
- data/app/components/better_ui/forms/checkbox_component.rb +419 -0
- data/app/components/better_ui/forms/checkbox_group_component/checkbox_group_component.html.erb +40 -0
- data/app/components/better_ui/forms/checkbox_group_component.rb +363 -0
- data/app/components/better_ui/forms/number_input_component/number_input_component.html.erb +40 -0
- data/app/components/better_ui/forms/number_input_component.rb +320 -0
- data/app/components/better_ui/forms/password_input_component/password_input_component.html.erb +71 -0
- data/app/components/better_ui/forms/password_input_component.rb +206 -0
- data/app/components/better_ui/forms/text_input_component/text_input_component.html.erb +40 -0
- data/app/components/better_ui/forms/text_input_component.rb +258 -0
- data/app/components/better_ui/forms/textarea_component/textarea_component.html.erb +40 -0
- data/app/components/better_ui/forms/textarea_component.rb +329 -0
- data/app/form_builders/better_ui/ui_form_builder.rb +467 -0
- data/app/helpers/better_ui/application_helper.rb +325 -58
- data/app/views/layouts/better_ui/application.html.erb +1 -1
- data/config/routes.rb +1 -0
- data/lib/better_ui/engine.rb +34 -5
- data/lib/better_ui/version.rb +1 -1
- data/lib/better_ui.rb +32 -5
- data/lib/generators/better_ui/install/USAGE +44 -0
- data/lib/generators/better_ui/install/install_generator.rb +87 -0
- data/lib/generators/better_ui/install/templates/better_ui_theme.css.tt +280 -0
- data/lib/tasks/better_ui_tasks.rake +39 -4
- metadata +52 -200
- data/app/components/better_ui/application/card/component.html.erb +0 -20
- data/app/components/better_ui/application/card/component.rb +0 -214
- data/app/components/better_ui/application/main/component.html.erb +0 -9
- data/app/components/better_ui/application/main/component.rb +0 -123
- data/app/components/better_ui/application/navbar/component.html.erb +0 -92
- data/app/components/better_ui/application/navbar/component.rb +0 -136
- data/app/components/better_ui/application/sidebar/component.html.erb +0 -249
- data/app/components/better_ui/application/sidebar/component.rb +0 -187
- data/app/components/better_ui/general/accordion/component.html.erb +0 -5
- data/app/components/better_ui/general/accordion/component.rb +0 -92
- data/app/components/better_ui/general/accordion/item_component.html.erb +0 -12
- data/app/components/better_ui/general/accordion/item_component.rb +0 -176
- data/app/components/better_ui/general/alert/component.html.erb +0 -32
- data/app/components/better_ui/general/alert/component.rb +0 -242
- data/app/components/better_ui/general/avatar/component.html.erb +0 -20
- data/app/components/better_ui/general/avatar/component.rb +0 -301
- data/app/components/better_ui/general/badge/component.html.erb +0 -23
- data/app/components/better_ui/general/badge/component.rb +0 -248
- data/app/components/better_ui/general/breadcrumb/component.html.erb +0 -15
- data/app/components/better_ui/general/breadcrumb/component.rb +0 -187
- data/app/components/better_ui/general/button/component.html.erb +0 -34
- data/app/components/better_ui/general/button/component.rb +0 -214
- data/app/components/better_ui/general/divider/component.html.erb +0 -10
- data/app/components/better_ui/general/divider/component.rb +0 -226
- data/app/components/better_ui/general/dropdown/component.html.erb +0 -28
- data/app/components/better_ui/general/dropdown/component.rb +0 -192
- data/app/components/better_ui/general/dropdown/divider_component.html.erb +0 -1
- data/app/components/better_ui/general/dropdown/divider_component.rb +0 -41
- data/app/components/better_ui/general/dropdown/item_component.html.erb +0 -6
- data/app/components/better_ui/general/dropdown/item_component.rb +0 -119
- data/app/components/better_ui/general/field/component.html.erb +0 -27
- data/app/components/better_ui/general/field/component.rb +0 -37
- data/app/components/better_ui/general/grid/cell_component.html.erb +0 -3
- data/app/components/better_ui/general/grid/cell_component.rb +0 -390
- data/app/components/better_ui/general/grid/component.html.erb +0 -3
- data/app/components/better_ui/general/grid/component.rb +0 -301
- data/app/components/better_ui/general/heading/component.html.erb +0 -22
- data/app/components/better_ui/general/heading/component.rb +0 -257
- data/app/components/better_ui/general/icon/component.html.erb +0 -7
- data/app/components/better_ui/general/icon/component.rb +0 -240
- data/app/components/better_ui/general/input/checkbox/component.html.erb +0 -5
- data/app/components/better_ui/general/input/checkbox/component.rb +0 -238
- data/app/components/better_ui/general/input/datetime/component.html.erb +0 -5
- data/app/components/better_ui/general/input/datetime/component.rb +0 -223
- data/app/components/better_ui/general/input/pin/component.html.erb +0 -1
- data/app/components/better_ui/general/input/pin/component.rb +0 -201
- data/app/components/better_ui/general/input/radio/component.html.erb +0 -5
- data/app/components/better_ui/general/input/radio/component.rb +0 -230
- data/app/components/better_ui/general/input/rating/component.html.erb +0 -4
- data/app/components/better_ui/general/input/rating/component.rb +0 -272
- data/app/components/better_ui/general/input/select/component.html.erb +0 -78
- data/app/components/better_ui/general/input/select/component.rb +0 -249
- data/app/components/better_ui/general/input/select/select_component.html.erb +0 -5
- data/app/components/better_ui/general/input/select/select_component.rb +0 -37
- data/app/components/better_ui/general/input/text/component.html.erb +0 -5
- data/app/components/better_ui/general/input/text/component.rb +0 -171
- data/app/components/better_ui/general/input/textarea/component.html.erb +0 -5
- data/app/components/better_ui/general/input/textarea/component.rb +0 -166
- data/app/components/better_ui/general/input/toggle/component.html.erb +0 -5
- data/app/components/better_ui/general/input/toggle/component.rb +0 -242
- data/app/components/better_ui/general/link/component.html.erb +0 -18
- data/app/components/better_ui/general/link/component.rb +0 -258
- data/app/components/better_ui/general/modal/component.html.erb +0 -5
- data/app/components/better_ui/general/modal/component.rb +0 -47
- data/app/components/better_ui/general/modal/modal_component.html.erb +0 -52
- data/app/components/better_ui/general/modal/modal_component.rb +0 -160
- data/app/components/better_ui/general/pagination/component.html.erb +0 -85
- data/app/components/better_ui/general/pagination/component.rb +0 -216
- data/app/components/better_ui/general/panel/component.html.erb +0 -28
- data/app/components/better_ui/general/panel/component.rb +0 -249
- data/app/components/better_ui/general/progress/component.html.erb +0 -11
- data/app/components/better_ui/general/progress/component.rb +0 -160
- data/app/components/better_ui/general/spinner/component.html.erb +0 -35
- data/app/components/better_ui/general/spinner/component.rb +0 -93
- data/app/components/better_ui/general/table/component.html.erb +0 -5
- data/app/components/better_ui/general/table/component.rb +0 -217
- data/app/components/better_ui/general/table/tbody_component.html.erb +0 -3
- data/app/components/better_ui/general/table/tbody_component.rb +0 -30
- data/app/components/better_ui/general/table/td_component.html.erb +0 -3
- data/app/components/better_ui/general/table/td_component.rb +0 -44
- data/app/components/better_ui/general/table/tfoot_component.html.erb +0 -3
- data/app/components/better_ui/general/table/tfoot_component.rb +0 -28
- data/app/components/better_ui/general/table/th_component.html.erb +0 -6
- data/app/components/better_ui/general/table/th_component.rb +0 -51
- data/app/components/better_ui/general/table/thead_component.html.erb +0 -3
- data/app/components/better_ui/general/table/thead_component.rb +0 -28
- data/app/components/better_ui/general/table/tr_component.html.erb +0 -3
- data/app/components/better_ui/general/table/tr_component.rb +0 -30
- data/app/components/better_ui/general/tabs/component.html.erb +0 -11
- data/app/components/better_ui/general/tabs/component.rb +0 -120
- data/app/components/better_ui/general/tabs/panel_component.html.erb +0 -3
- data/app/components/better_ui/general/tabs/panel_component.rb +0 -37
- data/app/components/better_ui/general/tabs/tab_component.html.erb +0 -13
- data/app/components/better_ui/general/tabs/tab_component.rb +0 -111
- data/app/components/better_ui/general/tag/component.html.erb +0 -3
- data/app/components/better_ui/general/tag/component.rb +0 -104
- data/app/components/better_ui/general/text/component.html.erb +0 -1
- data/app/components/better_ui/general/text/component.rb +0 -194
- data/app/components/better_ui/general/tooltip/component.html.erb +0 -7
- data/app/components/better_ui/general/tooltip/component.rb +0 -239
- data/app/helpers/better_ui/application/components/card/card_helper.rb +0 -96
- data/app/helpers/better_ui/application/components/card.rb +0 -11
- data/app/helpers/better_ui/application/components/main/main_helper.rb +0 -64
- data/app/helpers/better_ui/application/components/navbar/navbar_helper.rb +0 -77
- data/app/helpers/better_ui/application/components/sidebar/sidebar_helper.rb +0 -51
- data/app/helpers/better_ui/general/components/accordion/accordion_helper.rb +0 -73
- data/app/helpers/better_ui/general/components/alert/alert_helper.rb +0 -57
- data/app/helpers/better_ui/general/components/avatar/avatar_helper.rb +0 -29
- data/app/helpers/better_ui/general/components/badge/badge_helper.rb +0 -53
- data/app/helpers/better_ui/general/components/breadcrumb/breadcrumb_helper.rb +0 -37
- data/app/helpers/better_ui/general/components/button/button_helper.rb +0 -65
- data/app/helpers/better_ui/general/components/container/container_helper.rb +0 -60
- data/app/helpers/better_ui/general/components/divider/divider_helper.rb +0 -63
- data/app/helpers/better_ui/general/components/dropdown/divider_helper.rb +0 -32
- data/app/helpers/better_ui/general/components/dropdown/dropdown_helper.rb +0 -88
- data/app/helpers/better_ui/general/components/dropdown/item_helper.rb +0 -68
- data/app/helpers/better_ui/general/components/field/field_helper.rb +0 -26
- data/app/helpers/better_ui/general/components/grid/grid_helper.rb +0 -145
- data/app/helpers/better_ui/general/components/heading/heading_helper.rb +0 -72
- data/app/helpers/better_ui/general/components/icon/icon_helper.rb +0 -16
- data/app/helpers/better_ui/general/components/input/checkbox/checkbox_helper.rb +0 -81
- data/app/helpers/better_ui/general/components/input/datetime/datetime_helper.rb +0 -91
- data/app/helpers/better_ui/general/components/input/pin/pin_helper.rb +0 -76
- data/app/helpers/better_ui/general/components/input/radio/radio_helper.rb +0 -79
- data/app/helpers/better_ui/general/components/input/radio_group/radio_group_helper.rb +0 -124
- data/app/helpers/better_ui/general/components/input/rating/rating_helper.rb +0 -70
- data/app/helpers/better_ui/general/components/input/select/select_helper.rb +0 -86
- data/app/helpers/better_ui/general/components/input/text/text_helper.rb +0 -138
- data/app/helpers/better_ui/general/components/input/textarea/textarea_helper.rb +0 -73
- data/app/helpers/better_ui/general/components/input/toggle/toggle_helper.rb +0 -77
- data/app/helpers/better_ui/general/components/link/link_helper.rb +0 -89
- data/app/helpers/better_ui/general/components/modal/modal_helper.rb +0 -85
- data/app/helpers/better_ui/general/components/pagination/pagination_helper.rb +0 -82
- data/app/helpers/better_ui/general/components/panel/panel_helper.rb +0 -83
- data/app/helpers/better_ui/general/components/progress/progress_helper.rb +0 -53
- data/app/helpers/better_ui/general/components/spinner/spinner_helper.rb +0 -19
- data/app/helpers/better_ui/general/components/table/table_helper.rb +0 -53
- data/app/helpers/better_ui/general/components/table/tbody_helper.rb +0 -13
- data/app/helpers/better_ui/general/components/table/td_helper.rb +0 -19
- data/app/helpers/better_ui/general/components/table/tfoot_helper.rb +0 -13
- data/app/helpers/better_ui/general/components/table/th_helper.rb +0 -19
- data/app/helpers/better_ui/general/components/table/thead_helper.rb +0 -13
- data/app/helpers/better_ui/general/components/table/tr_helper.rb +0 -13
- data/app/helpers/better_ui/general/components/tabs/panel_helper.rb +0 -62
- data/app/helpers/better_ui/general/components/tabs/tab_helper.rb +0 -55
- data/app/helpers/better_ui/general/components/tabs/tabs_helper.rb +0 -95
- data/app/helpers/better_ui/general/components/tag/tag_helper.rb +0 -26
- data/app/helpers/better_ui/general/components/text/text_helper.rb +0 -83
- data/app/helpers/better_ui/general/components/tooltip/tooltip_helper.rb +0 -60
- data/app/jobs/better_ui/application_job.rb +0 -4
- data/app/mailers/better_ui/application_mailer.rb +0 -6
- data/config/initializers/lookbook.rb +0 -23
- data/lib/better_ui/railtie.rb +0 -20
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
<div class="<%= card_classes %>" <%= options.map { |k, v| "#{k}=\"#{v}\"" }.join(' ').html_safe %>>
|
|
2
|
-
<p class="<%= title_classes %>"><%= title %></p>
|
|
3
|
-
<div class="mt-2 flex items-baseline justify-between">
|
|
4
|
-
<p class="<%= value_classes %>"><%= value %></p>
|
|
5
|
-
<% if show_trend? %>
|
|
6
|
-
<span class="<%= trend_classes %>">
|
|
7
|
-
<% if trend_up? %>
|
|
8
|
-
<svg xmlns="http://www.w3.org/2000/svg" class="<%= trend_icon_size %>" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
9
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 10l7-7m0 0l7 7m-7-7v18" />
|
|
10
|
-
</svg>
|
|
11
|
-
<% else %>
|
|
12
|
-
<svg xmlns="http://www.w3.org/2000/svg" class="<%= trend_icon_size %>" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
13
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 14l-7 7m0 0l-7-7m7 7V3" />
|
|
14
|
-
</svg>
|
|
15
|
-
<% end %>
|
|
16
|
-
<%= change %>
|
|
17
|
-
</span>
|
|
18
|
-
<% end %>
|
|
19
|
-
</div>
|
|
20
|
-
</div>
|
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module BetterUi
|
|
4
|
-
module Application
|
|
5
|
-
module Card
|
|
6
|
-
class Component < ViewComponent::Base
|
|
7
|
-
# Costanti per le classi CSS
|
|
8
|
-
CARD_THEME = {
|
|
9
|
-
default: 'bg-gray-900 border-gray-800',
|
|
10
|
-
white: 'bg-white border-gray-200',
|
|
11
|
-
red: 'bg-red-50 border-red-200',
|
|
12
|
-
rose: 'bg-rose-50 border-rose-200',
|
|
13
|
-
orange: 'bg-orange-50 border-orange-200',
|
|
14
|
-
green: 'bg-green-50 border-green-200',
|
|
15
|
-
blue: 'bg-blue-50 border-blue-200',
|
|
16
|
-
yellow: 'bg-yellow-50 border-yellow-200',
|
|
17
|
-
violet: 'bg-violet-50 border-violet-200',
|
|
18
|
-
purple: 'bg-purple-50 border-purple-200'
|
|
19
|
-
}.freeze
|
|
20
|
-
|
|
21
|
-
CARD_SIZE = {
|
|
22
|
-
small: 'p-4',
|
|
23
|
-
medium: 'p-6',
|
|
24
|
-
large: 'p-8'
|
|
25
|
-
}.freeze
|
|
26
|
-
|
|
27
|
-
CARD_ROUNDED = {
|
|
28
|
-
none: 'rounded-none',
|
|
29
|
-
small: 'rounded-md',
|
|
30
|
-
medium: 'rounded-lg',
|
|
31
|
-
large: 'rounded-xl',
|
|
32
|
-
full: 'rounded-2xl'
|
|
33
|
-
}.freeze
|
|
34
|
-
|
|
35
|
-
CARD_SHADOW = {
|
|
36
|
-
none: 'shadow-none',
|
|
37
|
-
small: 'shadow-sm',
|
|
38
|
-
medium: 'shadow-md',
|
|
39
|
-
large: 'shadow-lg'
|
|
40
|
-
}.freeze
|
|
41
|
-
|
|
42
|
-
CARD_TREND_COLOR = {
|
|
43
|
-
green: 'text-green-600',
|
|
44
|
-
red: 'text-red-600',
|
|
45
|
-
blue: 'text-blue-600',
|
|
46
|
-
yellow: 'text-yellow-600',
|
|
47
|
-
purple: 'text-purple-600',
|
|
48
|
-
indigo: 'text-indigo-600',
|
|
49
|
-
gray: 'text-gray-600'
|
|
50
|
-
}.freeze
|
|
51
|
-
|
|
52
|
-
CARD_TITLE_SIZE = {
|
|
53
|
-
small: 'text-xs',
|
|
54
|
-
medium: 'text-sm',
|
|
55
|
-
large: 'text-base'
|
|
56
|
-
}.freeze
|
|
57
|
-
|
|
58
|
-
CARD_VALUE_SIZE = {
|
|
59
|
-
small: 'text-lg',
|
|
60
|
-
medium: 'text-2xl',
|
|
61
|
-
large: 'text-3xl'
|
|
62
|
-
}.freeze
|
|
63
|
-
|
|
64
|
-
def initialize(
|
|
65
|
-
title:,
|
|
66
|
-
value:,
|
|
67
|
-
trend: nil,
|
|
68
|
-
change: nil,
|
|
69
|
-
color: :green,
|
|
70
|
-
theme: :default,
|
|
71
|
-
size: :medium,
|
|
72
|
-
rounded: :medium,
|
|
73
|
-
shadow: :small,
|
|
74
|
-
classes: nil,
|
|
75
|
-
**options
|
|
76
|
-
)
|
|
77
|
-
@title = title
|
|
78
|
-
@value = value
|
|
79
|
-
@trend = trend
|
|
80
|
-
@change = change
|
|
81
|
-
@color = color
|
|
82
|
-
@theme = theme
|
|
83
|
-
@size = size
|
|
84
|
-
@rounded = rounded
|
|
85
|
-
@shadow = shadow
|
|
86
|
-
@classes = classes
|
|
87
|
-
@options = options
|
|
88
|
-
|
|
89
|
-
validate_params
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
private
|
|
93
|
-
|
|
94
|
-
attr_reader :title, :value, :trend, :change, :color, :theme, :size, :rounded, :shadow, :classes, :options
|
|
95
|
-
|
|
96
|
-
def validate_params
|
|
97
|
-
validate_theme
|
|
98
|
-
validate_size
|
|
99
|
-
validate_rounded
|
|
100
|
-
validate_shadow
|
|
101
|
-
validate_trend
|
|
102
|
-
validate_color
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def validate_theme
|
|
106
|
-
return if CARD_THEME.key?(theme)
|
|
107
|
-
|
|
108
|
-
raise ArgumentError, "Invalid theme: #{theme}. Valid options: #{CARD_THEME.keys.join(', ')}"
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def validate_size
|
|
112
|
-
return if CARD_SIZE.key?(size)
|
|
113
|
-
|
|
114
|
-
raise ArgumentError, "Invalid size: #{size}. Valid options: #{CARD_SIZE.keys.join(', ')}"
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
def validate_rounded
|
|
118
|
-
return if CARD_ROUNDED.key?(rounded)
|
|
119
|
-
|
|
120
|
-
raise ArgumentError, "Invalid rounded: #{rounded}. Valid options: #{CARD_ROUNDED.keys.join(', ')}"
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
def validate_shadow
|
|
124
|
-
return if CARD_SHADOW.key?(shadow)
|
|
125
|
-
|
|
126
|
-
raise ArgumentError, "Invalid shadow: #{shadow}. Valid options: #{CARD_SHADOW.keys.join(', ')}"
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def validate_trend
|
|
130
|
-
return if trend.nil? || [:up, :down].include?(trend)
|
|
131
|
-
|
|
132
|
-
raise ArgumentError, "Invalid trend: #{trend}. Valid options: :up, :down, nil"
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def validate_color
|
|
136
|
-
return if CARD_TREND_COLOR.key?(color)
|
|
137
|
-
|
|
138
|
-
raise ArgumentError, "Invalid color: #{color}. Valid options: #{CARD_TREND_COLOR.keys.join(', ')}"
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def card_classes
|
|
142
|
-
base_classes = [
|
|
143
|
-
CARD_THEME[theme],
|
|
144
|
-
CARD_SIZE[size],
|
|
145
|
-
CARD_ROUNDED[rounded],
|
|
146
|
-
CARD_SHADOW[shadow],
|
|
147
|
-
'border'
|
|
148
|
-
]
|
|
149
|
-
|
|
150
|
-
base_classes << classes if classes.present?
|
|
151
|
-
base_classes.compact.join(' ')
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
def title_classes
|
|
155
|
-
base_classes = [
|
|
156
|
-
CARD_TITLE_SIZE[size],
|
|
157
|
-
'font-medium'
|
|
158
|
-
]
|
|
159
|
-
|
|
160
|
-
if theme == :default
|
|
161
|
-
base_classes << 'text-gray-300'
|
|
162
|
-
else
|
|
163
|
-
base_classes << 'text-gray-500'
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
base_classes.join(' ')
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
def value_classes
|
|
170
|
-
base_classes = [
|
|
171
|
-
CARD_VALUE_SIZE[size],
|
|
172
|
-
'font-semibold'
|
|
173
|
-
]
|
|
174
|
-
|
|
175
|
-
if theme == :default
|
|
176
|
-
base_classes << 'text-white'
|
|
177
|
-
else
|
|
178
|
-
base_classes << 'text-gray-900'
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
base_classes.join(' ')
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
def trend_classes
|
|
185
|
-
base_classes = [
|
|
186
|
-
CARD_TREND_COLOR[color],
|
|
187
|
-
'text-sm font-medium flex items-center'
|
|
188
|
-
]
|
|
189
|
-
|
|
190
|
-
base_classes.join(' ')
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
def show_trend?
|
|
194
|
-
trend.present? && change.present?
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
def trend_up?
|
|
198
|
-
trend == :up
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
def trend_icon_size
|
|
202
|
-
case size
|
|
203
|
-
when :small
|
|
204
|
-
'h-3 w-3 mr-0.5'
|
|
205
|
-
when :medium
|
|
206
|
-
'h-4 w-4 mr-0.5'
|
|
207
|
-
when :large
|
|
208
|
-
'h-5 w-5 mr-1'
|
|
209
|
-
end
|
|
210
|
-
end
|
|
211
|
-
end
|
|
212
|
-
end
|
|
213
|
-
end
|
|
214
|
-
end
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
<main class="w-full <%= get_layout_class %> <%= get_padding_class(padding) %><%= classes ? ' ' + classes : '' %>">
|
|
2
|
-
<div class="h-[calc(100vh-81px)] p-4">
|
|
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
|
-
<div class="h-full overflow-y-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]">
|
|
5
|
-
<%= content %>
|
|
6
|
-
</div>
|
|
7
|
-
</div>
|
|
8
|
-
</div>
|
|
9
|
-
</main>
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module BetterUi
|
|
4
|
-
module Application
|
|
5
|
-
module Main
|
|
6
|
-
class Component < ViewComponent::Base
|
|
7
|
-
attr_reader :padding, :inner_padding, :rounded, :shadow, :with_sidebar, :sidebar_width, :classes
|
|
8
|
-
|
|
9
|
-
# Arrotondamento bordi con classi Tailwind dirette
|
|
10
|
-
MAIN_ROUNDED = {
|
|
11
|
-
none: "",
|
|
12
|
-
small: "rounded-lg",
|
|
13
|
-
medium: "rounded-xl",
|
|
14
|
-
large: "rounded-2xl",
|
|
15
|
-
full: "rounded-full"
|
|
16
|
-
}.freeze
|
|
17
|
-
|
|
18
|
-
# Ombre con classi Tailwind dirette
|
|
19
|
-
MAIN_SHADOW = {
|
|
20
|
-
none: "",
|
|
21
|
-
small: "shadow-sm",
|
|
22
|
-
medium: "shadow-md",
|
|
23
|
-
large: "shadow-lg"
|
|
24
|
-
}.freeze
|
|
25
|
-
|
|
26
|
-
# Padding con classi Tailwind dirette
|
|
27
|
-
MAIN_PADDING = {
|
|
28
|
-
true: "p-6",
|
|
29
|
-
false: "p-0"
|
|
30
|
-
}.freeze
|
|
31
|
-
|
|
32
|
-
# Classi layout per sidebar
|
|
33
|
-
MAIN_LAYOUT = {
|
|
34
|
-
sidebar: { sm: "pl-48", md: "pl-64", lg: "pl-72", xl: "pl-80" }, # Con Sidebar
|
|
35
|
-
none: "" # Senza sidebar
|
|
36
|
-
}.freeze
|
|
37
|
-
|
|
38
|
-
# Larghezza sidebar (deve corrispondere a SIDEBAR_WIDTHS del componente Sidebar)
|
|
39
|
-
MAIN_SIDEBAR_WIDTH = {
|
|
40
|
-
sm: 48,
|
|
41
|
-
md: 64,
|
|
42
|
-
lg: 72,
|
|
43
|
-
xl: 80
|
|
44
|
-
}.freeze
|
|
45
|
-
|
|
46
|
-
# @param padding [Boolean] Se applicare il padding al contenitore principale
|
|
47
|
-
# @param inner_padding [Boolean] Se applicare il padding al contenitore interno
|
|
48
|
-
# @param rounded [Symbol] Tipo di border-radius del contenitore interno (:none, :small, :medium, :large, :full), default :small
|
|
49
|
-
# @param shadow [Symbol] Tipo di ombra del contenitore interno (:none, :small, :medium, :large), default :medium
|
|
50
|
-
# @param with_sidebar [Boolean] Se lasciare lo spazio per la sidebar
|
|
51
|
-
# @param sidebar_width [Symbol] Larghezza della sidebar (:sm, :md, :lg, :xl), default :md
|
|
52
|
-
# @param classes [String] Classi CSS aggiuntive per il contenitore principale
|
|
53
|
-
def initialize(
|
|
54
|
-
padding: true,
|
|
55
|
-
inner_padding: true,
|
|
56
|
-
rounded: :small,
|
|
57
|
-
shadow: :medium,
|
|
58
|
-
with_sidebar: true,
|
|
59
|
-
sidebar_width: :md,
|
|
60
|
-
classes: nil
|
|
61
|
-
)
|
|
62
|
-
@padding = padding
|
|
63
|
-
@inner_padding = inner_padding
|
|
64
|
-
@rounded = rounded.to_sym
|
|
65
|
-
@shadow = shadow.to_sym
|
|
66
|
-
@with_sidebar = with_sidebar
|
|
67
|
-
@sidebar_width = sidebar_width.to_sym
|
|
68
|
-
@classes = classes
|
|
69
|
-
|
|
70
|
-
validate_params
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
private
|
|
76
|
-
|
|
77
|
-
def get_layout_class
|
|
78
|
-
if with_sidebar
|
|
79
|
-
MAIN_LAYOUT[:sidebar][@sidebar_width] || MAIN_LAYOUT[:sidebar][:md]
|
|
80
|
-
else
|
|
81
|
-
MAIN_LAYOUT[:none]
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def get_padding_class(enabled)
|
|
86
|
-
MAIN_PADDING[enabled] || MAIN_PADDING[false]
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def get_rounded_class
|
|
90
|
-
MAIN_ROUNDED[@rounded] || MAIN_ROUNDED[:small]
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def get_shadow_class
|
|
94
|
-
MAIN_SHADOW[@shadow] || MAIN_SHADOW[:medium]
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def validate_params
|
|
98
|
-
validate_rounded
|
|
99
|
-
validate_shadow
|
|
100
|
-
validate_sidebar_width if with_sidebar
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def validate_rounded
|
|
104
|
-
unless MAIN_ROUNDED.keys.include?(@rounded)
|
|
105
|
-
raise ArgumentError, "L'arrotondamento deve essere uno tra: #{MAIN_ROUNDED.keys.join(', ')}"
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def validate_shadow
|
|
110
|
-
unless MAIN_SHADOW.keys.include?(@shadow)
|
|
111
|
-
raise ArgumentError, "L'ombra deve essere una tra: #{MAIN_SHADOW.keys.join(', ')}"
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
def validate_sidebar_width
|
|
116
|
-
unless MAIN_SIDEBAR_WIDTH.keys.include?(@sidebar_width)
|
|
117
|
-
raise ArgumentError, "La larghezza della sidebar deve essere una tra: #{MAIN_SIDEBAR_WIDTH.keys.join(', ')}"
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
end
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
<header class="<%= container_classes %>">
|
|
2
|
-
<div class="flex items-center justify-between">
|
|
3
|
-
<!-- Left side - custom content-->
|
|
4
|
-
<div class="flex items-center">
|
|
5
|
-
<%= content %>
|
|
6
|
-
</div>
|
|
7
|
-
|
|
8
|
-
<!-- User actions -->
|
|
9
|
-
<div class="flex items-center space-x-4">
|
|
10
|
-
<% if has_actions? %>
|
|
11
|
-
<% actions.each do |action| %>
|
|
12
|
-
<div class="flex-shrink-0">
|
|
13
|
-
<% if action[:type] == :button %>
|
|
14
|
-
<% if action[:href].present? %>
|
|
15
|
-
<a
|
|
16
|
-
href="<%= action[:href] %>"
|
|
17
|
-
class="inline-flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors duration-150 <%= action[:theme] == :primary ? 'bg-gray-900 text-white hover:bg-gray-700' : 'bg-gray-100 text-gray-700 hover:bg-gray-200' %>"
|
|
18
|
-
>
|
|
19
|
-
<% if action[:icon].present? %>
|
|
20
|
-
<%= bui_icon(action[:icon], size: :small) %>
|
|
21
|
-
<% if action[:label].present? %>
|
|
22
|
-
<span class="ml-2"><%= action[:label] %></span>
|
|
23
|
-
<% end %>
|
|
24
|
-
<% else %>
|
|
25
|
-
<%= action[:label] %>
|
|
26
|
-
<% end %>
|
|
27
|
-
</a>
|
|
28
|
-
<% else %>
|
|
29
|
-
<button
|
|
30
|
-
type="button"
|
|
31
|
-
class="inline-flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors duration-150 <%= action[:theme] == :primary ? 'bg-gray-900 text-white hover:bg-gray-700' : 'bg-gray-100 text-gray-700 hover:bg-gray-200' %>"
|
|
32
|
-
<% if action[:data].present? %>
|
|
33
|
-
<% action[:data].each do |key, value| %>
|
|
34
|
-
data-<%= key %>="<%= value %>"
|
|
35
|
-
<% end %>
|
|
36
|
-
<% end %>
|
|
37
|
-
>
|
|
38
|
-
<% if action[:icon].present? %>
|
|
39
|
-
<%= bui_icon(action[:icon], size: :small) %>
|
|
40
|
-
<% if action[:label].present? %>
|
|
41
|
-
<span class="ml-2"><%= action[:label] %></span>
|
|
42
|
-
<% end %>
|
|
43
|
-
<% else %>
|
|
44
|
-
<%= action[:label] %>
|
|
45
|
-
<% end %>
|
|
46
|
-
</button>
|
|
47
|
-
<% end %>
|
|
48
|
-
<% elsif action[:type] == :avatar %>
|
|
49
|
-
<% if action[:href].present? %>
|
|
50
|
-
<a href="<%= action[:href] %>" class="flex-shrink-0 hover:opacity-75 transition-opacity duration-150">
|
|
51
|
-
<% end %>
|
|
52
|
-
|
|
53
|
-
<% if action[:avatar].is_a?(Hash) %>
|
|
54
|
-
<%= bui_avatar(**action[:avatar]) %>
|
|
55
|
-
<% else %>
|
|
56
|
-
<%= action[:avatar].html_safe %>
|
|
57
|
-
<% end %>
|
|
58
|
-
|
|
59
|
-
<% if action[:href].present? %>
|
|
60
|
-
</a>
|
|
61
|
-
<% end %>
|
|
62
|
-
<% elsif action[:type] == :icon %>
|
|
63
|
-
<% if action[:href].present? %>
|
|
64
|
-
<a
|
|
65
|
-
href="<%= action[:href] %>"
|
|
66
|
-
class="p-2 text-gray-600 hover:text-gray-900 hover:bg-gray-100 rounded-md transition-colors duration-150"
|
|
67
|
-
>
|
|
68
|
-
<%= bui_icon(action[:icon], size: :medium) %>
|
|
69
|
-
</a>
|
|
70
|
-
<% else %>
|
|
71
|
-
<button
|
|
72
|
-
type="button"
|
|
73
|
-
class="p-2 text-gray-600 hover:text-gray-900 hover:bg-gray-100 rounded-md transition-colors duration-150"
|
|
74
|
-
<% if action[:data].present? %>
|
|
75
|
-
<% action[:data].each do |key, value| %>
|
|
76
|
-
data-<%= key %>="<%= value %>"
|
|
77
|
-
<% end %>
|
|
78
|
-
<% end %>
|
|
79
|
-
>
|
|
80
|
-
<%= bui_icon(action[:icon], size: :medium) %>
|
|
81
|
-
</button>
|
|
82
|
-
<% end %>
|
|
83
|
-
<% else %>
|
|
84
|
-
<!-- Custom content -->
|
|
85
|
-
<%= action[:content].html_safe if action[:content].present? %>
|
|
86
|
-
<% end %>
|
|
87
|
-
</div>
|
|
88
|
-
<% end %>
|
|
89
|
-
<% end %>
|
|
90
|
-
</div>
|
|
91
|
-
</div>
|
|
92
|
-
</header>
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module BetterUi
|
|
4
|
-
module Application
|
|
5
|
-
module Navbar
|
|
6
|
-
class Component < ViewComponent::Base
|
|
7
|
-
# Include degli helper per utilizzare bui_icon e bui_avatar
|
|
8
|
-
include BetterUi::General::Components::Icon::IconHelper
|
|
9
|
-
include BetterUi::General::Components::Avatar::AvatarHelper
|
|
10
|
-
|
|
11
|
-
attr_reader :theme, :shadow, :border, :actions, :classes, :with_sidebar, :sidebar_width
|
|
12
|
-
|
|
13
|
-
# Temi navbar con classi Tailwind dirette
|
|
14
|
-
NAVBAR_THEME = {
|
|
15
|
-
default: "bg-white text-gray-900 border-gray-200",
|
|
16
|
-
white: "bg-white text-gray-900 border-gray-200",
|
|
17
|
-
red: "bg-red-50 text-red-900 border-red-200",
|
|
18
|
-
rose: "bg-rose-50 text-rose-900 border-rose-200",
|
|
19
|
-
orange: "bg-orange-50 text-orange-900 border-orange-200",
|
|
20
|
-
green: "bg-green-50 text-green-900 border-green-200",
|
|
21
|
-
blue: "bg-blue-50 text-blue-900 border-blue-200",
|
|
22
|
-
yellow: "bg-yellow-50 text-yellow-900 border-yellow-200",
|
|
23
|
-
violet: "bg-violet-50 text-violet-900 border-violet-200"
|
|
24
|
-
}.freeze
|
|
25
|
-
|
|
26
|
-
# Ombre navbar con classi Tailwind dirette
|
|
27
|
-
NAVBAR_SHADOW = {
|
|
28
|
-
none: "",
|
|
29
|
-
small: "shadow-sm",
|
|
30
|
-
medium: "shadow-md",
|
|
31
|
-
large: "shadow-lg"
|
|
32
|
-
}.freeze
|
|
33
|
-
|
|
34
|
-
# Larghezze sidebar con valori numerici per utilizzo in classi custom
|
|
35
|
-
NAVBAR_SIDEBAR_WIDTH = {
|
|
36
|
-
sm: 48,
|
|
37
|
-
md: 64,
|
|
38
|
-
lg: 72,
|
|
39
|
-
xl: 80
|
|
40
|
-
}.freeze
|
|
41
|
-
|
|
42
|
-
# @param theme [Symbol] Tema colori (default, white, red, rose, orange, green, blue, yellow, violet), default :default
|
|
43
|
-
# @param shadow [Symbol] Tipo di ombra (none, small, medium, large), default :small
|
|
44
|
-
# @param border [Boolean] Se mostrare il bordo inferiore, default true
|
|
45
|
-
# @param actions [Array] Array di azioni/pulsanti a destra
|
|
46
|
-
# @param classes [String] Classi CSS aggiuntive
|
|
47
|
-
# @param with_sidebar [Boolean] Se la navbar è affiancata a una sidebar, default false
|
|
48
|
-
# @param sidebar_width [Symbol] Larghezza della sidebar affiancata (:sm, :md, :lg, :xl), default :md
|
|
49
|
-
def initialize(
|
|
50
|
-
theme: :default,
|
|
51
|
-
shadow: :small,
|
|
52
|
-
border: false,
|
|
53
|
-
actions: [],
|
|
54
|
-
classes: nil,
|
|
55
|
-
with_sidebar: false,
|
|
56
|
-
sidebar_width: :md
|
|
57
|
-
)
|
|
58
|
-
@theme = theme.to_sym
|
|
59
|
-
@shadow = shadow.to_sym
|
|
60
|
-
@border = border
|
|
61
|
-
@actions = actions || []
|
|
62
|
-
@classes = classes
|
|
63
|
-
@with_sidebar = with_sidebar
|
|
64
|
-
@sidebar_width = sidebar_width.to_sym
|
|
65
|
-
|
|
66
|
-
validate_params
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def container_classes
|
|
70
|
-
base_classes = %w[h-[81px] px-6 py-4]
|
|
71
|
-
|
|
72
|
-
# Width
|
|
73
|
-
if with_sidebar
|
|
74
|
-
sidebar_width_value = NAVBAR_SIDEBAR_WIDTH[@sidebar_width] || NAVBAR_SIDEBAR_WIDTH[:md]
|
|
75
|
-
base_classes << "pl-#{sidebar_width_value}"
|
|
76
|
-
base_classes << "ml-auto"
|
|
77
|
-
else
|
|
78
|
-
base_classes << "w-full"
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
# Tema
|
|
82
|
-
base_classes.concat(theme_classes.split)
|
|
83
|
-
|
|
84
|
-
# Shadow
|
|
85
|
-
base_classes << shadow_class if shadow != :none
|
|
86
|
-
|
|
87
|
-
# Border
|
|
88
|
-
base_classes << "border-b" if border
|
|
89
|
-
|
|
90
|
-
# Classi aggiuntive
|
|
91
|
-
base_classes << classes if classes.present?
|
|
92
|
-
|
|
93
|
-
base_classes.compact.join(" ")
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def has_actions?
|
|
97
|
-
actions.present? && actions.any?
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
private
|
|
101
|
-
|
|
102
|
-
def theme_classes
|
|
103
|
-
NAVBAR_THEME[@theme] || NAVBAR_THEME[:default]
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def shadow_class
|
|
107
|
-
NAVBAR_SHADOW[@shadow] || NAVBAR_SHADOW[:small]
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
def validate_params
|
|
111
|
-
validate_theme
|
|
112
|
-
validate_shadow
|
|
113
|
-
validate_sidebar_width if with_sidebar
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def validate_theme
|
|
117
|
-
unless NAVBAR_THEME.keys.include?(@theme)
|
|
118
|
-
raise ArgumentError, "Il tema deve essere uno tra: #{NAVBAR_THEME.keys.join(', ')}"
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def validate_shadow
|
|
123
|
-
unless NAVBAR_SHADOW.keys.include?(@shadow)
|
|
124
|
-
raise ArgumentError, "L'ombra deve essere una tra: #{NAVBAR_SHADOW.keys.join(', ')}"
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
def validate_sidebar_width
|
|
129
|
-
unless NAVBAR_SIDEBAR_WIDTH.keys.include?(@sidebar_width)
|
|
130
|
-
raise ArgumentError, "La larghezza della sidebar deve essere una tra: #{NAVBAR_SIDEBAR_WIDTH.keys.join(', ')}"
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
end
|