better_ui_tmp 0.5.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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +211 -0
- data/Rakefile +8 -0
- data/app/assets/builds/application.js +1 -0
- data/app/assets/builds/better_ui.css +1 -0
- data/app/assets/stylesheets/better_ui.scss +3 -0
- data/app/components/better_ui/application/main/component.html.erb +5 -0
- data/app/components/better_ui/application/main/component.rb +99 -0
- data/app/components/better_ui/application/navbar/component.html.erb +219 -0
- data/app/components/better_ui/application/navbar/component.rb +148 -0
- data/app/components/better_ui/application/sidebar/component.html.erb +184 -0
- data/app/components/better_ui/application/sidebar/component.rb +129 -0
- data/app/components/better_ui/general/alert/component.html.erb +32 -0
- data/app/components/better_ui/general/alert/component.rb +242 -0
- data/app/components/better_ui/general/avatar/component.html.erb +20 -0
- data/app/components/better_ui/general/avatar/component.rb +301 -0
- data/app/components/better_ui/general/badge/component.html.erb +23 -0
- data/app/components/better_ui/general/badge/component.rb +248 -0
- data/app/components/better_ui/general/breadcrumb/component.html.erb +15 -0
- data/app/components/better_ui/general/breadcrumb/component.rb +186 -0
- data/app/components/better_ui/general/button/component.html.erb +34 -0
- data/app/components/better_ui/general/button/component.rb +214 -0
- data/app/components/better_ui/general/card/component.html.erb +21 -0
- data/app/components/better_ui/general/card/component.rb +37 -0
- data/app/components/better_ui/general/container/component.html.erb +8 -0
- data/app/components/better_ui/general/container/component.rb +158 -0
- data/app/components/better_ui/general/divider/component.html.erb +10 -0
- data/app/components/better_ui/general/divider/component.rb +226 -0
- data/app/components/better_ui/general/heading/component.html.erb +22 -0
- data/app/components/better_ui/general/heading/component.rb +257 -0
- data/app/components/better_ui/general/icon/component.html.erb +1 -0
- data/app/components/better_ui/general/icon/component.rb +222 -0
- data/app/components/better_ui/general/link/component.html.erb +18 -0
- data/app/components/better_ui/general/link/component.rb +255 -0
- data/app/components/better_ui/general/panel/component.html.erb +28 -0
- data/app/components/better_ui/general/panel/component.rb +249 -0
- data/app/components/better_ui/general/progress/component.html.erb +11 -0
- data/app/components/better_ui/general/progress/component.rb +160 -0
- data/app/components/better_ui/general/spinner/component.html.erb +35 -0
- data/app/components/better_ui/general/spinner/component.rb +93 -0
- data/app/components/better_ui/general/table/component.html.erb +5 -0
- data/app/components/better_ui/general/table/component.rb +217 -0
- data/app/components/better_ui/general/table/tbody_component.html.erb +3 -0
- data/app/components/better_ui/general/table/tbody_component.rb +30 -0
- data/app/components/better_ui/general/table/td_component.html.erb +3 -0
- data/app/components/better_ui/general/table/td_component.rb +44 -0
- data/app/components/better_ui/general/table/tfoot_component.html.erb +3 -0
- data/app/components/better_ui/general/table/tfoot_component.rb +28 -0
- data/app/components/better_ui/general/table/th_component.html.erb +6 -0
- data/app/components/better_ui/general/table/th_component.rb +51 -0
- data/app/components/better_ui/general/table/thead_component.html.erb +3 -0
- data/app/components/better_ui/general/table/thead_component.rb +28 -0
- data/app/components/better_ui/general/table/tr_component.html.erb +3 -0
- data/app/components/better_ui/general/table/tr_component.rb +30 -0
- data/app/components/better_ui/general/tag/component.html.erb +3 -0
- data/app/components/better_ui/general/tag/component.rb +104 -0
- data/app/components/better_ui/general/tooltip/component.html.erb +7 -0
- data/app/components/better_ui/general/tooltip/component.rb +239 -0
- data/app/controllers/better_ui/application_controller.rb +5 -0
- data/app/helpers/better_ui/application/components/main/main_helper.rb +42 -0
- data/app/helpers/better_ui/application/components/main.rb +13 -0
- data/app/helpers/better_ui/application/components/navbar/navbar_helper.rb +51 -0
- data/app/helpers/better_ui/application/components/navbar.rb +13 -0
- data/app/helpers/better_ui/application/components/sidebar/sidebar_helper.rb +51 -0
- data/app/helpers/better_ui/application/components/sidebar.rb +13 -0
- data/app/helpers/better_ui/application_helper.rb +10 -0
- data/app/helpers/better_ui/form_helper.rb +5 -0
- data/app/helpers/better_ui/general/components/alert/alert_helper.rb +29 -0
- data/app/helpers/better_ui/general/components/alert.rb +13 -0
- data/app/helpers/better_ui/general/components/avatar/avatar_helper.rb +29 -0
- data/app/helpers/better_ui/general/components/avatar.rb +13 -0
- data/app/helpers/better_ui/general/components/badge/badge_helper.rb +53 -0
- data/app/helpers/better_ui/general/components/badge.rb +13 -0
- data/app/helpers/better_ui/general/components/breadcrumb/breadcrumb_helper.rb +37 -0
- data/app/helpers/better_ui/general/components/breadcrumb.rb +13 -0
- data/app/helpers/better_ui/general/components/button/button_helper.rb +65 -0
- data/app/helpers/better_ui/general/components/button.rb +13 -0
- data/app/helpers/better_ui/general/components/card/card_helper.rb +37 -0
- data/app/helpers/better_ui/general/components/card.rb +13 -0
- data/app/helpers/better_ui/general/components/container/container_helper.rb +60 -0
- data/app/helpers/better_ui/general/components/container.rb +13 -0
- data/app/helpers/better_ui/general/components/divider/divider_helper.rb +63 -0
- data/app/helpers/better_ui/general/components/divider.rb +13 -0
- data/app/helpers/better_ui/general/components/heading/heading_helper.rb +72 -0
- data/app/helpers/better_ui/general/components/heading.rb +13 -0
- data/app/helpers/better_ui/general/components/icon/icon_helper.rb +16 -0
- data/app/helpers/better_ui/general/components/icon.rb +13 -0
- data/app/helpers/better_ui/general/components/link/link_helper.rb +89 -0
- data/app/helpers/better_ui/general/components/link.rb +13 -0
- data/app/helpers/better_ui/general/components/panel/panel_helper.rb +83 -0
- data/app/helpers/better_ui/general/components/panel.rb +13 -0
- data/app/helpers/better_ui/general/components/progress/progress_helper.rb +53 -0
- data/app/helpers/better_ui/general/components/progress.rb +11 -0
- data/app/helpers/better_ui/general/components/spinner/spinner_helper.rb +17 -0
- data/app/helpers/better_ui/general/components/spinner.rb +10 -0
- data/app/helpers/better_ui/general/components/table/table_helper.rb +13 -0
- data/app/helpers/better_ui/general/components/table/tbody_helper.rb +13 -0
- data/app/helpers/better_ui/general/components/table/td_helper.rb +19 -0
- data/app/helpers/better_ui/general/components/table/tfoot_helper.rb +13 -0
- data/app/helpers/better_ui/general/components/table/th_helper.rb +19 -0
- data/app/helpers/better_ui/general/components/table/thead_helper.rb +13 -0
- data/app/helpers/better_ui/general/components/table/tr_helper.rb +13 -0
- data/app/helpers/better_ui/general/components/table.rb +25 -0
- data/app/helpers/better_ui/general/components/tag/tag_helper.rb +26 -0
- data/app/helpers/better_ui/general/components/tag.rb +15 -0
- data/app/helpers/better_ui/general/components/tooltip/tooltip_helper.rb +60 -0
- data/app/helpers/better_ui/general/components/tooltip.rb +13 -0
- data/app/helpers/better_ui/general_helper.rb +24 -0
- data/app/helpers/better_ui_helper.rb +16 -0
- data/app/javascript/application.js +1 -0
- data/app/jobs/better_ui/application_job.rb +4 -0
- data/app/mailers/better_ui/application_mailer.rb +6 -0
- data/app/models/better_ui/application_record.rb +5 -0
- data/app/views/components/better_ui/general/table/_custom_body_row.html.erb +17 -0
- data/app/views/components/better_ui/general/table/_custom_footer_rows.html.erb +17 -0
- data/app/views/components/better_ui/general/table/_custom_header_rows.html.erb +12 -0
- data/app/views/layouts/component_preview.html.erb +32 -0
- data/config/initializers/lookbook.rb +23 -0
- data/config/routes.rb +3 -0
- data/lib/better_ui/engine.rb +109 -0
- data/lib/better_ui/version.rb +3 -0
- data/lib/better_ui.rb +37 -0
- data/lib/generators/better_ui/install_generator.rb +103 -0
- data/lib/generators/better_ui/stylesheet_generator.rb +159 -0
- data/lib/generators/better_ui/templates/components/_avatar.scss +200 -0
- data/lib/generators/better_ui/templates/components/_badge.scss +154 -0
- data/lib/generators/better_ui/templates/components/_breadcrumb.scss +106 -0
- data/lib/generators/better_ui/templates/components/_button.scss +109 -0
- data/lib/generators/better_ui/templates/components/_card.scss +60 -0
- data/lib/generators/better_ui/templates/components/_heading.scss +81 -0
- data/lib/generators/better_ui/templates/components/_icon.scss +134 -0
- data/lib/generators/better_ui/templates/components/_index.scss +17 -0
- data/lib/generators/better_ui/templates/components/_link.scss +100 -0
- data/lib/generators/better_ui/templates/components/_panel.scss +104 -0
- data/lib/generators/better_ui/templates/components/_spinner.scss +129 -0
- data/lib/generators/better_ui/templates/components/_table.scss +156 -0
- data/lib/generators/better_ui/templates/components/_variables.scss +0 -0
- data/lib/generators/better_ui/templates/components_stylesheet.scss +35 -0
- data/lib/generators/better_ui/templates/index.scss +18 -0
- data/lib/generators/better_ui/templates/initializer.rb +41 -0
- data/lib/tasks/better_ui_tasks.rake +4 -0
- metadata +260 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
<div <%= tag.attributes(container_attributes) %>>
|
2
|
+
<div class="flex-shrink-0">
|
3
|
+
<svg class="<%= svg_classes %> animate-spin" viewBox="0 0 24 24" fill="none">
|
4
|
+
<circle
|
5
|
+
cx="12"
|
6
|
+
cy="12"
|
7
|
+
r="10"
|
8
|
+
stroke="currentColor"
|
9
|
+
stroke-width="2"
|
10
|
+
stroke-linecap="round"
|
11
|
+
stroke-dasharray="32"
|
12
|
+
stroke-dashoffset="32">
|
13
|
+
<animate
|
14
|
+
attributeName="stroke-dasharray"
|
15
|
+
dur="2s"
|
16
|
+
values="0 32;16 16;0 32;0 32"
|
17
|
+
repeatCount="indefinite" />
|
18
|
+
<animate
|
19
|
+
attributeName="stroke-dashoffset"
|
20
|
+
dur="2s"
|
21
|
+
values="0;-16;-32;-32"
|
22
|
+
repeatCount="indefinite" />
|
23
|
+
<animateTransform
|
24
|
+
attributeName="transform"
|
25
|
+
type="rotate"
|
26
|
+
dur="2s"
|
27
|
+
values="0 12 12;360 12 12"
|
28
|
+
repeatCount="indefinite" />
|
29
|
+
</circle>
|
30
|
+
</svg>
|
31
|
+
</div>
|
32
|
+
<% if show_label? %>
|
33
|
+
<span class="text-sm font-medium"><%= label %></span>
|
34
|
+
<% end %>
|
35
|
+
</div>
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module BetterUi
|
2
|
+
module General
|
3
|
+
module Spinner
|
4
|
+
class Component < ViewComponent::Base
|
5
|
+
THEMES = %i[default white red rose orange green blue yellow violet].freeze
|
6
|
+
SIZES = %i[small medium large].freeze
|
7
|
+
STYLES = %i[default outline].freeze
|
8
|
+
|
9
|
+
# Classi base sempre presenti
|
10
|
+
SPINNER_BASE_CLASSES = "inline-flex items-center gap-2"
|
11
|
+
|
12
|
+
# Dimensioni SVG con classi Tailwind dirette
|
13
|
+
SPINNER_SIZES = {
|
14
|
+
small: "w-4 h-4", # 16px
|
15
|
+
medium: "w-6 h-6", # 24px
|
16
|
+
large: "w-8 h-8" # 32px
|
17
|
+
}
|
18
|
+
|
19
|
+
# Temi colore con classi Tailwind dirette
|
20
|
+
SPINNER_THEMES = {
|
21
|
+
default: "text-gray-900",
|
22
|
+
white: "text-white",
|
23
|
+
red: "text-red-500",
|
24
|
+
rose: "text-rose-500",
|
25
|
+
orange: "text-orange-500",
|
26
|
+
green: "text-green-500",
|
27
|
+
blue: "text-blue-500",
|
28
|
+
yellow: "text-yellow-500",
|
29
|
+
violet: "text-violet-500"
|
30
|
+
}
|
31
|
+
|
32
|
+
# Stili con classi Tailwind dirette
|
33
|
+
SPINNER_STYLES = {
|
34
|
+
default: "",
|
35
|
+
outline: "opacity-75"
|
36
|
+
}
|
37
|
+
|
38
|
+
def initialize(theme: :default, size: :medium, style: :default, label: nil, **html_options)
|
39
|
+
@theme = theme.to_sym
|
40
|
+
@size = size.to_sym
|
41
|
+
@style = style.to_sym
|
42
|
+
@label = label
|
43
|
+
@html_options = html_options
|
44
|
+
|
45
|
+
validate_options!
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
attr_reader :theme, :size, :style, :label, :html_options
|
51
|
+
|
52
|
+
def validate_options!
|
53
|
+
raise ArgumentError, "Theme deve essere uno di: #{THEMES.join(', ')}" unless THEMES.include?(theme)
|
54
|
+
raise ArgumentError, "Size deve essere uno di: #{SIZES.join(', ')}" unless SIZES.include?(size)
|
55
|
+
raise ArgumentError, "Style deve essere uno di: #{STYLES.join(', ')}" unless STYLES.include?(style)
|
56
|
+
end
|
57
|
+
|
58
|
+
def combined_classes
|
59
|
+
[
|
60
|
+
SPINNER_BASE_CLASSES,
|
61
|
+
get_spinner_theme_classes,
|
62
|
+
get_spinner_style_classes,
|
63
|
+
html_options[:class]
|
64
|
+
].compact.join(' ')
|
65
|
+
end
|
66
|
+
|
67
|
+
def get_spinner_theme_classes
|
68
|
+
SPINNER_THEMES[theme] || SPINNER_THEMES[:default]
|
69
|
+
end
|
70
|
+
|
71
|
+
def get_spinner_style_classes
|
72
|
+
SPINNER_STYLES[style] || SPINNER_STYLES[:default]
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_spinner_size_classes
|
76
|
+
SPINNER_SIZES[size] || SPINNER_SIZES[:medium]
|
77
|
+
end
|
78
|
+
|
79
|
+
def container_attributes
|
80
|
+
html_options.except(:class).merge(class: combined_classes)
|
81
|
+
end
|
82
|
+
|
83
|
+
def svg_classes
|
84
|
+
get_spinner_size_classes
|
85
|
+
end
|
86
|
+
|
87
|
+
def show_label?
|
88
|
+
label.present?
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,217 @@
|
|
1
|
+
module BetterUi
|
2
|
+
module General
|
3
|
+
module Table
|
4
|
+
class Component < ViewComponent::Base
|
5
|
+
attr_reader :data, :headers, :caption, :striped, :hoverable, :bordered, :compact, :minimal, :footer,
|
6
|
+
:header_rows_partial, :body_row_partial, :footer_rows_partial, :thead_partial, :tfoot_partial
|
7
|
+
|
8
|
+
# Classi base sempre presenti
|
9
|
+
TABLE_BASE_CLASSES = "w-full table-auto border-collapse"
|
10
|
+
|
11
|
+
# Temi di colore con classi Tailwind dirette
|
12
|
+
TABLE_THEME = {
|
13
|
+
default: "bg-gray-50 text-gray-900",
|
14
|
+
white: "bg-white text-gray-900",
|
15
|
+
red: "bg-red-50 text-red-900",
|
16
|
+
rose: "bg-rose-50 text-rose-900",
|
17
|
+
orange: "bg-orange-50 text-orange-900",
|
18
|
+
green: "bg-green-50 text-green-900",
|
19
|
+
blue: "bg-blue-50 text-blue-900",
|
20
|
+
yellow: "bg-yellow-50 text-yellow-900",
|
21
|
+
violet: "bg-violet-50 text-violet-900"
|
22
|
+
}.freeze
|
23
|
+
|
24
|
+
# Opzioni di bordi arrotondati con classi Tailwind dirette
|
25
|
+
TABLE_RADIUS = {
|
26
|
+
none: "rounded-none",
|
27
|
+
small: "rounded-md",
|
28
|
+
medium: "rounded-lg",
|
29
|
+
large: "rounded-xl",
|
30
|
+
full: "rounded-full"
|
31
|
+
}.freeze
|
32
|
+
|
33
|
+
|
34
|
+
# Classi per container
|
35
|
+
CONTAINER_BASE_CLASSES = "overflow-x-auto"
|
36
|
+
|
37
|
+
# Classi per elementi della tabella
|
38
|
+
THEAD_CLASSES = "bg-gray-100 border-b border-gray-200"
|
39
|
+
TBODY_CLASSES = ""
|
40
|
+
TFOOT_CLASSES = "bg-gray-50 border-t border-gray-200"
|
41
|
+
TR_CLASSES = "border-b border-gray-100 hover:bg-gray-50"
|
42
|
+
TH_CLASSES = "px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
|
43
|
+
TD_CLASSES = "px-4 py-3 text-sm text-gray-900"
|
44
|
+
TF_CLASSES = "px-4 py-3 text-sm font-medium text-gray-900"
|
45
|
+
CAPTION_CLASSES = "mb-2 text-sm text-gray-600 text-left"
|
46
|
+
|
47
|
+
def initialize(
|
48
|
+
data: nil,
|
49
|
+
headers: nil,
|
50
|
+
caption: nil,
|
51
|
+
theme: :default,
|
52
|
+
radius: :small,
|
53
|
+
striped: false,
|
54
|
+
hoverable: false,
|
55
|
+
bordered: false,
|
56
|
+
compact: false,
|
57
|
+
minimal: false,
|
58
|
+
footer: nil,
|
59
|
+
header_rows_partial: nil,
|
60
|
+
body_row_partial: nil,
|
61
|
+
footer_rows_partial: nil,
|
62
|
+
thead_partial: nil,
|
63
|
+
tfoot_partial: nil,
|
64
|
+
**html_options
|
65
|
+
)
|
66
|
+
@data = data || []
|
67
|
+
@headers = headers
|
68
|
+
@caption = caption
|
69
|
+
@theme = theme.to_sym
|
70
|
+
@radius = radius.to_sym
|
71
|
+
# Flag boolean combinabili
|
72
|
+
@striped = !!striped
|
73
|
+
@hoverable = !!hoverable
|
74
|
+
@bordered = !!bordered
|
75
|
+
@compact = !!compact
|
76
|
+
@minimal = !!minimal
|
77
|
+
@footer = footer.is_a?(Array) ? footer : nil
|
78
|
+
@header_rows_partial = header_rows_partial
|
79
|
+
@body_row_partial = body_row_partial
|
80
|
+
@footer_rows_partial = footer_rows_partial
|
81
|
+
@thead_partial = thead_partial
|
82
|
+
@tfoot_partial = tfoot_partial
|
83
|
+
@html_options = html_options
|
84
|
+
|
85
|
+
validate_params
|
86
|
+
end
|
87
|
+
|
88
|
+
# Combina tutte le classi per la tabella
|
89
|
+
def combined_classes
|
90
|
+
[
|
91
|
+
TABLE_BASE_CLASSES,
|
92
|
+
get_theme_class,
|
93
|
+
@bordered ? "border border-gray-200" : nil,
|
94
|
+
@striped ? "[&_tbody_tr:nth-child(odd)]:bg-gray-50" : nil,
|
95
|
+
@hoverable ? "[&_tbody_tr]:hover:bg-gray-50" : nil,
|
96
|
+
@compact ? "[&_td]:py-1 [&_th]:py-1" : nil,
|
97
|
+
@minimal ? "border-0" : nil,
|
98
|
+
@html_options[:class]
|
99
|
+
].compact.join(" ")
|
100
|
+
end
|
101
|
+
|
102
|
+
# Restituisce gli attributi HTML per la tabella
|
103
|
+
def table_attributes
|
104
|
+
attrs = @html_options.except(:class)
|
105
|
+
attrs[:class] = combined_classes
|
106
|
+
attrs
|
107
|
+
end
|
108
|
+
|
109
|
+
# Combina le classi per il container
|
110
|
+
def table_container_classes
|
111
|
+
[
|
112
|
+
CONTAINER_BASE_CLASSES,
|
113
|
+
get_radius_class
|
114
|
+
].compact.join(" ")
|
115
|
+
end
|
116
|
+
|
117
|
+
# Restituisce gli attributi HTML per il container
|
118
|
+
def container_attributes
|
119
|
+
{
|
120
|
+
class: table_container_classes
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
def get_radius_class
|
125
|
+
TABLE_RADIUS[@radius] || TABLE_RADIUS[:small]
|
126
|
+
end
|
127
|
+
|
128
|
+
def get_theme_class
|
129
|
+
TABLE_THEME[@theme] || TABLE_THEME[:default]
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
def caption_classes
|
134
|
+
CAPTION_CLASSES
|
135
|
+
end
|
136
|
+
|
137
|
+
def thead_classes
|
138
|
+
THEAD_CLASSES
|
139
|
+
end
|
140
|
+
|
141
|
+
def tbody_classes
|
142
|
+
TBODY_CLASSES
|
143
|
+
end
|
144
|
+
|
145
|
+
def tfoot_classes
|
146
|
+
TFOOT_CLASSES
|
147
|
+
end
|
148
|
+
|
149
|
+
def tr_classes(index)
|
150
|
+
TR_CLASSES
|
151
|
+
end
|
152
|
+
|
153
|
+
def th_classes
|
154
|
+
TH_CLASSES
|
155
|
+
end
|
156
|
+
|
157
|
+
def td_classes
|
158
|
+
TD_CLASSES
|
159
|
+
end
|
160
|
+
|
161
|
+
def tf_classes
|
162
|
+
TF_CLASSES
|
163
|
+
end
|
164
|
+
|
165
|
+
def headers_for_display
|
166
|
+
return @headers if @headers.present?
|
167
|
+
return [] if @data.empty?
|
168
|
+
|
169
|
+
case first_item = @data.first
|
170
|
+
when Hash
|
171
|
+
first_item.keys
|
172
|
+
when -> (item) { item.respond_to?(:attributes) }
|
173
|
+
first_item.attributes.keys - %w[id created_at updated_at]
|
174
|
+
else
|
175
|
+
[]
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
# Ottiene il valore di una cella in modo consistente
|
180
|
+
def get_cell_value(row, header)
|
181
|
+
if row.is_a?(Hash)
|
182
|
+
row[header.to_s] || row[header.to_sym] || "—"
|
183
|
+
elsif row.respond_to?(header.to_sym)
|
184
|
+
row.send(header.to_sym)
|
185
|
+
elsif row.is_a?(Array) && headers_for_display.index(header)
|
186
|
+
row[headers_for_display.index(header)] || "—"
|
187
|
+
else
|
188
|
+
"—"
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def render?
|
193
|
+
true
|
194
|
+
end
|
195
|
+
|
196
|
+
private
|
197
|
+
|
198
|
+
def validate_params
|
199
|
+
validate_theme
|
200
|
+
validate_radius
|
201
|
+
end
|
202
|
+
|
203
|
+
def validate_theme
|
204
|
+
unless TABLE_THEME.keys.include?(@theme)
|
205
|
+
raise ArgumentError, "Il tema deve essere uno tra: #{TABLE_THEME.keys.join(', ')}"
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def validate_radius
|
210
|
+
unless TABLE_RADIUS.keys.include?(@radius)
|
211
|
+
raise ArgumentError, "Il radius deve essere uno tra: #{TABLE_RADIUS.keys.join(', ')}"
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module BetterUi
|
2
|
+
module General
|
3
|
+
module Table
|
4
|
+
class TbodyComponent < ViewComponent::Base
|
5
|
+
attr_reader :theme, :striped, :hoverable
|
6
|
+
|
7
|
+
def initialize(theme: :default, striped: false, hoverable: false, **html_options)
|
8
|
+
@theme = theme.to_sym
|
9
|
+
@striped = !!striped
|
10
|
+
@hoverable = !!hoverable
|
11
|
+
@html_options = html_options
|
12
|
+
end
|
13
|
+
|
14
|
+
def tbody_classes
|
15
|
+
[
|
16
|
+
@striped ? "[&_tr:nth-child(odd)]:bg-gray-50" : nil,
|
17
|
+
@hoverable ? "[&_tr]:hover:bg-gray-50" : nil,
|
18
|
+
@html_options[:class]
|
19
|
+
].compact.join(" ")
|
20
|
+
end
|
21
|
+
|
22
|
+
def tbody_attributes
|
23
|
+
attrs = @html_options.except(:class)
|
24
|
+
attrs[:class] = tbody_classes
|
25
|
+
attrs
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module BetterUi
|
2
|
+
module General
|
3
|
+
module Table
|
4
|
+
class TdComponent < ViewComponent::Base
|
5
|
+
attr_reader :theme, :align, :compact
|
6
|
+
|
7
|
+
def initialize(theme: :default, align: :left, compact: false, **html_options)
|
8
|
+
@theme = theme.to_sym
|
9
|
+
@align = align.to_sym
|
10
|
+
@compact = !!compact
|
11
|
+
@html_options = html_options
|
12
|
+
end
|
13
|
+
|
14
|
+
def td_classes
|
15
|
+
[
|
16
|
+
"px-4 py-3 text-sm text-gray-900",
|
17
|
+
alignment_class,
|
18
|
+
@compact ? "py-1" : nil,
|
19
|
+
@html_options[:class]
|
20
|
+
].compact.join(" ")
|
21
|
+
end
|
22
|
+
|
23
|
+
def td_attributes
|
24
|
+
attrs = @html_options.except(:class)
|
25
|
+
attrs[:class] = td_classes
|
26
|
+
attrs
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def alignment_class
|
32
|
+
case @align
|
33
|
+
when :center
|
34
|
+
"text-center"
|
35
|
+
when :right
|
36
|
+
"text-right"
|
37
|
+
else
|
38
|
+
"text-left"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module BetterUi
|
2
|
+
module General
|
3
|
+
module Table
|
4
|
+
class TfootComponent < ViewComponent::Base
|
5
|
+
attr_reader :theme, :bordered
|
6
|
+
|
7
|
+
def initialize(theme: :default, bordered: false, **html_options)
|
8
|
+
@theme = theme.to_sym
|
9
|
+
@bordered = !!bordered
|
10
|
+
@html_options = html_options
|
11
|
+
end
|
12
|
+
|
13
|
+
def tfoot_classes
|
14
|
+
[
|
15
|
+
"bg-gray-50 border-t border-gray-200",
|
16
|
+
@html_options[:class]
|
17
|
+
].compact.join(" ")
|
18
|
+
end
|
19
|
+
|
20
|
+
def tfoot_attributes
|
21
|
+
attrs = @html_options.except(:class)
|
22
|
+
attrs[:class] = tfoot_classes
|
23
|
+
attrs
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module BetterUi
|
2
|
+
module General
|
3
|
+
module Table
|
4
|
+
class ThComponent < ViewComponent::Base
|
5
|
+
attr_reader :theme, :sortable, :sorted, :sort_direction, :scope
|
6
|
+
|
7
|
+
def initialize(
|
8
|
+
theme: :default,
|
9
|
+
sortable: false,
|
10
|
+
sorted: false,
|
11
|
+
sort_direction: :asc,
|
12
|
+
scope: "col",
|
13
|
+
**html_options
|
14
|
+
)
|
15
|
+
@theme = theme.to_sym
|
16
|
+
@sortable = !!sortable
|
17
|
+
@sorted = !!sorted
|
18
|
+
@sort_direction = sort_direction.to_sym
|
19
|
+
@scope = scope
|
20
|
+
@html_options = html_options
|
21
|
+
end
|
22
|
+
|
23
|
+
def th_classes
|
24
|
+
[
|
25
|
+
"px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider",
|
26
|
+
@sortable ? "cursor-pointer hover:bg-gray-200" : nil,
|
27
|
+
@sorted ? "bg-gray-200" : nil,
|
28
|
+
@html_options[:class]
|
29
|
+
].compact.join(" ")
|
30
|
+
end
|
31
|
+
|
32
|
+
def th_attributes
|
33
|
+
attrs = @html_options.except(:class)
|
34
|
+
attrs[:class] = th_classes
|
35
|
+
attrs[:scope] = @scope
|
36
|
+
attrs
|
37
|
+
end
|
38
|
+
|
39
|
+
def sort_icon
|
40
|
+
return unless @sortable
|
41
|
+
|
42
|
+
if @sorted
|
43
|
+
@sort_direction == :asc ? "↑" : "↓"
|
44
|
+
else
|
45
|
+
"↕"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module BetterUi
|
2
|
+
module General
|
3
|
+
module Table
|
4
|
+
class TheadComponent < ViewComponent::Base
|
5
|
+
attr_reader :theme, :bordered
|
6
|
+
|
7
|
+
def initialize(theme: :default, bordered: false, **html_options)
|
8
|
+
@theme = theme.to_sym
|
9
|
+
@bordered = !!bordered
|
10
|
+
@html_options = html_options
|
11
|
+
end
|
12
|
+
|
13
|
+
def thead_classes
|
14
|
+
[
|
15
|
+
"bg-gray-100 border-b border-gray-200",
|
16
|
+
@html_options[:class]
|
17
|
+
].compact.join(" ")
|
18
|
+
end
|
19
|
+
|
20
|
+
def thead_attributes
|
21
|
+
attrs = @html_options.except(:class)
|
22
|
+
attrs[:class] = thead_classes
|
23
|
+
attrs
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module BetterUi
|
2
|
+
module General
|
3
|
+
module Table
|
4
|
+
class TrComponent < ViewComponent::Base
|
5
|
+
attr_reader :theme, :highlighted, :striped_index
|
6
|
+
|
7
|
+
def initialize(theme: :default, highlighted: false, striped_index: nil, **html_options)
|
8
|
+
@theme = theme.to_sym
|
9
|
+
@highlighted = !!highlighted
|
10
|
+
@striped_index = striped_index
|
11
|
+
@html_options = html_options
|
12
|
+
end
|
13
|
+
|
14
|
+
def tr_classes
|
15
|
+
[
|
16
|
+
"border-b border-gray-100",
|
17
|
+
@highlighted ? "bg-blue-50" : nil,
|
18
|
+
@html_options[:class]
|
19
|
+
].compact.join(" ")
|
20
|
+
end
|
21
|
+
|
22
|
+
def tr_attributes
|
23
|
+
attrs = @html_options.except(:class)
|
24
|
+
attrs[:class] = tr_classes
|
25
|
+
attrs
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|