okonomi_ui_kit 0.1.6 → 0.1.8
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 +163 -7
- data/app/assets/builds/okonomi_ui_kit/application.tailwind.css +292 -4
- data/app/helpers/okonomi_ui_kit/component.rb +81 -0
- data/app/helpers/okonomi_ui_kit/components/badge.rb +21 -16
- data/app/helpers/okonomi_ui_kit/components/breadcrumbs.rb +69 -0
- data/app/helpers/okonomi_ui_kit/components/button_base.rb +56 -0
- data/app/helpers/okonomi_ui_kit/components/button_tag.rb +23 -0
- data/app/helpers/okonomi_ui_kit/components/button_to.rb +23 -0
- data/app/helpers/okonomi_ui_kit/components/code.rb +73 -0
- data/app/helpers/okonomi_ui_kit/components/icon.rb +36 -0
- data/app/helpers/okonomi_ui_kit/components/link_to.rb +23 -0
- data/app/helpers/okonomi_ui_kit/components/page.rb +247 -0
- data/app/helpers/okonomi_ui_kit/components/table.rb +207 -0
- data/app/helpers/okonomi_ui_kit/components/typography.rb +29 -3
- data/app/helpers/okonomi_ui_kit/config.rb +20 -0
- data/app/helpers/okonomi_ui_kit/form_builder.rb +2 -2
- data/app/helpers/okonomi_ui_kit/t_w_merge.rb +108 -0
- data/app/helpers/okonomi_ui_kit/theme.rb +3 -26
- data/app/helpers/okonomi_ui_kit/ui_helper.rb +0 -40
- data/app/views/okonomi/components/breadcrumbs/_breadcrumbs.html.erb +46 -0
- data/app/views/okonomi/components/code/_code.html.erb +1 -0
- data/app/views/okonomi/components/icon/_icon.html.erb +38 -0
- data/app/views/okonomi/components/page/_page.html.erb +5 -0
- data/app/views/okonomi/components/table/_table.html.erb +3 -0
- data/app/views/okonomi/forms/tailwind/_upload_field.html.erb +2 -2
- data/app/views/okonomi/modals/_confirmation_modal.html.erb +2 -2
- data/app/views/okonomi/navigation/_link.html.erb +1 -1
- data/lib/okonomi_ui_kit/engine.rb +0 -5
- data/lib/okonomi_ui_kit/version.rb +1 -1
- metadata +18 -7
- data/app/helpers/okonomi_ui_kit/badge_helper.rb +0 -23
- data/app/helpers/okonomi_ui_kit/breadcrumbs_helper.rb +0 -60
- data/app/helpers/okonomi_ui_kit/icon_helper.rb +0 -39
- data/app/helpers/okonomi_ui_kit/page_builder_helper.rb +0 -217
- data/app/helpers/okonomi_ui_kit/table_helper.rb +0 -158
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: okonomi_ui_kit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Okonomi GmbH
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-08-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -1357,18 +1357,24 @@ files:
|
|
1357
1357
|
- app/controllers/okonomi_ui_kit/application_controller.rb
|
1358
1358
|
- app/helpers/okonomi_ui_kit/application_helper.rb
|
1359
1359
|
- app/helpers/okonomi_ui_kit/attribute_section_helper.rb
|
1360
|
-
- app/helpers/okonomi_ui_kit/badge_helper.rb
|
1361
|
-
- app/helpers/okonomi_ui_kit/breadcrumbs_helper.rb
|
1362
1360
|
- app/helpers/okonomi_ui_kit/component.rb
|
1363
1361
|
- app/helpers/okonomi_ui_kit/components/alert.rb
|
1364
1362
|
- app/helpers/okonomi_ui_kit/components/badge.rb
|
1363
|
+
- app/helpers/okonomi_ui_kit/components/breadcrumbs.rb
|
1364
|
+
- app/helpers/okonomi_ui_kit/components/button_base.rb
|
1365
|
+
- app/helpers/okonomi_ui_kit/components/button_tag.rb
|
1366
|
+
- app/helpers/okonomi_ui_kit/components/button_to.rb
|
1367
|
+
- app/helpers/okonomi_ui_kit/components/code.rb
|
1368
|
+
- app/helpers/okonomi_ui_kit/components/icon.rb
|
1369
|
+
- app/helpers/okonomi_ui_kit/components/link_to.rb
|
1370
|
+
- app/helpers/okonomi_ui_kit/components/page.rb
|
1371
|
+
- app/helpers/okonomi_ui_kit/components/table.rb
|
1365
1372
|
- app/helpers/okonomi_ui_kit/components/typography.rb
|
1373
|
+
- app/helpers/okonomi_ui_kit/config.rb
|
1366
1374
|
- app/helpers/okonomi_ui_kit/form_builder.rb
|
1367
|
-
- app/helpers/okonomi_ui_kit/icon_helper.rb
|
1368
1375
|
- app/helpers/okonomi_ui_kit/navigation_helper.rb
|
1369
|
-
- app/helpers/okonomi_ui_kit/page_builder_helper.rb
|
1370
1376
|
- app/helpers/okonomi_ui_kit/svg_icons.rb
|
1371
|
-
- app/helpers/okonomi_ui_kit/
|
1377
|
+
- app/helpers/okonomi_ui_kit/t_w_merge.rb
|
1372
1378
|
- app/helpers/okonomi_ui_kit/theme.rb
|
1373
1379
|
- app/helpers/okonomi_ui_kit/theme_helper.rb
|
1374
1380
|
- app/helpers/okonomi_ui_kit/ui_helper.rb
|
@@ -1386,6 +1392,11 @@ files:
|
|
1386
1392
|
- app/views/layouts/okonomi_ui_kit/application.html.erb
|
1387
1393
|
- app/views/okonomi/attribute_sections/_section.html.erb
|
1388
1394
|
- app/views/okonomi/components/alert/_alert.html.erb
|
1395
|
+
- app/views/okonomi/components/breadcrumbs/_breadcrumbs.html.erb
|
1396
|
+
- app/views/okonomi/components/code/_code.html.erb
|
1397
|
+
- app/views/okonomi/components/icon/_icon.html.erb
|
1398
|
+
- app/views/okonomi/components/page/_page.html.erb
|
1399
|
+
- app/views/okonomi/components/table/_table.html.erb
|
1389
1400
|
- app/views/okonomi/components/typography/_typography.html.erb
|
1390
1401
|
- app/views/okonomi/forms/tailwind/_checkbox_label.html.erb
|
1391
1402
|
- app/views/okonomi/forms/tailwind/_field.html.erb
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module OkonomiUiKit
|
2
|
-
module BadgeHelper
|
3
|
-
def badge(text, severity = :default, **options)
|
4
|
-
color_classes = case severity.to_sym
|
5
|
-
when :success
|
6
|
-
"bg-green-100 text-green-800"
|
7
|
-
when :danger
|
8
|
-
"bg-red-100 text-red-800"
|
9
|
-
when :info
|
10
|
-
"bg-blue-100 text-blue-800"
|
11
|
-
when :warning
|
12
|
-
"bg-yellow-100 text-yellow-800"
|
13
|
-
else
|
14
|
-
"bg-gray-100 text-gray-800"
|
15
|
-
end
|
16
|
-
|
17
|
-
base_classes = "inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium"
|
18
|
-
full_classes = "#{base_classes} #{color_classes} #{options[:class] || ''}".strip
|
19
|
-
|
20
|
-
tag.span(text, class: full_classes, **options.except(:class))
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
module OkonomiUiKit
|
2
|
-
module BreadcrumbsHelper
|
3
|
-
def breadcrumbs
|
4
|
-
content_tag(:nav, class: "flex", aria: { label: "Breadcrumb" }) do
|
5
|
-
content_tag(:ol, class: "flex items-center space-x-4", role: "list") do
|
6
|
-
builder = BreadcrumbBuilder.new(self)
|
7
|
-
yield builder
|
8
|
-
safe_join(builder.items)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
class BreadcrumbBuilder
|
14
|
-
attr_reader :items
|
15
|
-
|
16
|
-
def initialize(view)
|
17
|
-
@view = view
|
18
|
-
@items = []
|
19
|
-
@first = true
|
20
|
-
end
|
21
|
-
|
22
|
-
def link(label, url, icon: nil, current: false)
|
23
|
-
if @first
|
24
|
-
@items << @view.content_tag(:li) do
|
25
|
-
@view.content_tag(:div) do
|
26
|
-
if icon.present?
|
27
|
-
@view.link_to(url, class: "text-gray-400 hover:text-gray-500") do
|
28
|
-
@view.svg_icon(icon, class: "size-5") + @view.content_tag(:span, label, class: "sr-only")
|
29
|
-
end
|
30
|
-
else
|
31
|
-
@view.content_tag(:div, class: "flex items-center") do
|
32
|
-
@view.link_to(label, url, class: breadcrumb_classes(current, first: true), aria: (current ? { current: "page" } : {}))
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
@first = false
|
38
|
-
else
|
39
|
-
@items << @view.content_tag(:li) do
|
40
|
-
@view.content_tag(:div, class: "flex items-center") do
|
41
|
-
chevron + @view.link_to(label, url, class: breadcrumb_classes(current), aria: (current ? { current: "page" } : {}))
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
def chevron
|
50
|
-
@view.svg_icon("heroicons/solid/chevron-right", class: "size-5 shrink-0 text-gray-400")
|
51
|
-
end
|
52
|
-
|
53
|
-
def breadcrumb_classes(current, first: false)
|
54
|
-
base = "text-sm font-medium"
|
55
|
-
base = "#{base} ml-4" unless first
|
56
|
-
current ? "#{base} text-gray-500" : "#{base} text-gray-500 hover:text-gray-700"
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module OkonomiUiKit
|
4
|
-
module IconHelper
|
5
|
-
def icon_tag(icon, variant = :outlined, options = {})
|
6
|
-
if icon.is_a?(Icon)
|
7
|
-
doc = Nokogiri::HTML::DocumentFragment.parse icon.send(:"content_#{variant}")
|
8
|
-
svg = doc.at_css 'svg'
|
9
|
-
|
10
|
-
svg['class'] = options[:class] if options[:class].present?
|
11
|
-
svg['style'] = options[:style] if options[:style].present?
|
12
|
-
|
13
|
-
svg['width'] = options[:width] if options[:width].present?
|
14
|
-
svg['height'] = options[:height] if options[:height].present?
|
15
|
-
|
16
|
-
raw doc
|
17
|
-
else
|
18
|
-
svg_icon(icon, options)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def svg_icon(name, options = {})
|
23
|
-
if OkonomiUiKit::SvgIcons.exist?(name)
|
24
|
-
doc = Nokogiri::HTML::DocumentFragment.parse OkonomiUiKit::SvgIcons.read(name)
|
25
|
-
svg = doc.at_css 'svg'
|
26
|
-
|
27
|
-
svg['class'] = options[:class] if options[:class].present?
|
28
|
-
svg['style'] = options[:style] if options[:style].present?
|
29
|
-
|
30
|
-
svg['width'] = options[:width] if options[:width].present?
|
31
|
-
svg['height'] = options[:height] if options[:height].present?
|
32
|
-
else
|
33
|
-
doc = "<!-- SVG #{name} not found -->"
|
34
|
-
end
|
35
|
-
|
36
|
-
raw doc
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,217 +0,0 @@
|
|
1
|
-
module OkonomiUiKit
|
2
|
-
module PageBuilderHelper
|
3
|
-
def page(**options, &block)
|
4
|
-
builder = PageBuilder.new(self)
|
5
|
-
|
6
|
-
render 'okonomi/page_builder/page', builder: builder, options: options, &block
|
7
|
-
end
|
8
|
-
|
9
|
-
class PageBuilder
|
10
|
-
include ActionView::Helpers::TagHelper
|
11
|
-
include ActionView::Helpers::CaptureHelper
|
12
|
-
|
13
|
-
def initialize(template)
|
14
|
-
@template = template
|
15
|
-
end
|
16
|
-
|
17
|
-
def page_header(**options, &block)
|
18
|
-
header_builder = PageHeaderBuilder.new(@template)
|
19
|
-
yield(header_builder) if block_given?
|
20
|
-
header_builder.render
|
21
|
-
end
|
22
|
-
|
23
|
-
def section(**options, &block)
|
24
|
-
section_builder = SectionBuilder.new(@template)
|
25
|
-
yield(section_builder) if block_given?
|
26
|
-
section_builder.render
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def tag
|
32
|
-
@template.tag
|
33
|
-
end
|
34
|
-
|
35
|
-
def capture(*args, &block)
|
36
|
-
@template.capture(*args, &block)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
class PageHeaderBuilder
|
41
|
-
include ActionView::Helpers::TagHelper
|
42
|
-
include ActionView::Helpers::CaptureHelper
|
43
|
-
|
44
|
-
def initialize(template)
|
45
|
-
@template = template
|
46
|
-
@breadcrumbs_content = nil
|
47
|
-
@row_content = nil
|
48
|
-
end
|
49
|
-
|
50
|
-
def breadcrumbs(&block)
|
51
|
-
@breadcrumbs_content = @template.breadcrumbs(&block)
|
52
|
-
end
|
53
|
-
|
54
|
-
def row(&block)
|
55
|
-
row_builder = PageHeaderRowBuilder.new(@template)
|
56
|
-
yield(row_builder) if block_given?
|
57
|
-
@row_content = row_builder.render
|
58
|
-
end
|
59
|
-
|
60
|
-
def render
|
61
|
-
content = []
|
62
|
-
content << @breadcrumbs_content if @breadcrumbs_content
|
63
|
-
content << @row_content if @row_content
|
64
|
-
|
65
|
-
tag.div(class: "flex flex-col gap-2") do
|
66
|
-
@template.safe_join(content.compact)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
private
|
71
|
-
|
72
|
-
def tag
|
73
|
-
@template.tag
|
74
|
-
end
|
75
|
-
|
76
|
-
def capture(*args, &block)
|
77
|
-
@template.capture(*args, &block)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
class PageHeaderRowBuilder
|
82
|
-
include ActionView::Helpers::TagHelper
|
83
|
-
include ActionView::Helpers::CaptureHelper
|
84
|
-
|
85
|
-
def initialize(template)
|
86
|
-
@template = template
|
87
|
-
@title_content = nil
|
88
|
-
@actions_content = nil
|
89
|
-
end
|
90
|
-
|
91
|
-
def title(text, **options)
|
92
|
-
@title_content = tag.h1(text, class: "text-2xl font-bold leading-7 text-gray-900 truncate sm:text-3xl sm:tracking-tight")
|
93
|
-
end
|
94
|
-
|
95
|
-
def actions(&block)
|
96
|
-
@actions_content = tag.div(class: "mt-4 flex md:ml-4 md:mt-0 gap-2") do
|
97
|
-
capture(&block) if block_given?
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
def render
|
102
|
-
tag.div(class: "flex w-full justify-between items-center") do
|
103
|
-
content = []
|
104
|
-
content << @title_content if @title_content
|
105
|
-
content << @actions_content if @actions_content
|
106
|
-
@template.safe_join(content.compact)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
private
|
111
|
-
|
112
|
-
def tag
|
113
|
-
@template.tag
|
114
|
-
end
|
115
|
-
|
116
|
-
def capture(*args, &block)
|
117
|
-
@template.capture(*args, &block)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
class SectionBuilder
|
122
|
-
include ActionView::Helpers::TagHelper
|
123
|
-
include ActionView::Helpers::CaptureHelper
|
124
|
-
|
125
|
-
def initialize(template)
|
126
|
-
@template = template
|
127
|
-
@title_content = nil
|
128
|
-
@subtitle_content = nil
|
129
|
-
@actions_content = nil
|
130
|
-
@body_content = nil
|
131
|
-
end
|
132
|
-
|
133
|
-
def title(text, **options)
|
134
|
-
@title_content = tag.h3(text, class: "text-base/7 font-semibold text-gray-900")
|
135
|
-
end
|
136
|
-
|
137
|
-
def subtitle(text, **options)
|
138
|
-
@subtitle_content = tag.p(text, class: "mt-1 max-w-2xl text-sm/6 text-gray-500")
|
139
|
-
end
|
140
|
-
|
141
|
-
def actions(&block)
|
142
|
-
@actions_content = tag.div(class: "mt-4 flex md:ml-4 md:mt-0") do
|
143
|
-
capture(&block) if block_given?
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
def body(&block)
|
148
|
-
@body_content = tag.div do
|
149
|
-
tag.dl(class: "divide-y divide-gray-100") do
|
150
|
-
capture(&block) if block_given?
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
def attribute(label, value = nil, **options, &block)
|
156
|
-
content = if block_given?
|
157
|
-
capture(&block)
|
158
|
-
elsif value.respond_to?(:call)
|
159
|
-
value.call
|
160
|
-
else
|
161
|
-
value
|
162
|
-
end
|
163
|
-
|
164
|
-
tag.div(class: "py-6 sm:grid sm:grid-cols-3 sm:gap-4") do
|
165
|
-
dt_content = tag.dt(label, class: "text-sm font-medium text-gray-900")
|
166
|
-
dd_content = tag.dd(content, class: "mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0")
|
167
|
-
|
168
|
-
dt_content + dd_content
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
def render
|
173
|
-
tag.div(class: "overflow-hidden bg-white") do
|
174
|
-
header_content = build_header
|
175
|
-
content_parts = []
|
176
|
-
content_parts << header_content if header_content.present?
|
177
|
-
content_parts << @body_content if @body_content
|
178
|
-
@template.safe_join(content_parts.compact)
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
private
|
183
|
-
|
184
|
-
def build_header
|
185
|
-
return nil unless @title_content || @subtitle_content || @actions_content
|
186
|
-
|
187
|
-
tag.div(class: "py-6") do
|
188
|
-
if @actions_content
|
189
|
-
tag.div(class: "flex w-full justify-between items-start") do
|
190
|
-
title_section = tag.div do
|
191
|
-
content_parts = []
|
192
|
-
content_parts << @title_content if @title_content
|
193
|
-
content_parts << @subtitle_content if @subtitle_content
|
194
|
-
@template.safe_join(content_parts.compact)
|
195
|
-
end
|
196
|
-
|
197
|
-
title_section + @actions_content
|
198
|
-
end
|
199
|
-
else
|
200
|
-
content_parts = []
|
201
|
-
content_parts << @title_content if @title_content
|
202
|
-
content_parts << @subtitle_content if @subtitle_content
|
203
|
-
@template.safe_join(content_parts.compact)
|
204
|
-
end
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
def tag
|
209
|
-
@template.tag
|
210
|
-
end
|
211
|
-
|
212
|
-
def capture(*args, &block)
|
213
|
-
@template.capture(*args, &block)
|
214
|
-
end
|
215
|
-
end
|
216
|
-
end
|
217
|
-
end
|
@@ -1,158 +0,0 @@
|
|
1
|
-
module OkonomiUiKit
|
2
|
-
module TableHelper
|
3
|
-
def table(**options, &block)
|
4
|
-
builder = TableBuilder.new(self)
|
5
|
-
|
6
|
-
render 'okonomi/tables/table', builder: builder, options: options, &block
|
7
|
-
end
|
8
|
-
|
9
|
-
class TableBuilder
|
10
|
-
include ActionView::Helpers::TagHelper
|
11
|
-
include ActionView::Helpers::CaptureHelper
|
12
|
-
|
13
|
-
def initialize(template)
|
14
|
-
@template = template
|
15
|
-
@current_row_cells = []
|
16
|
-
@in_header = false
|
17
|
-
@in_body = false
|
18
|
-
end
|
19
|
-
|
20
|
-
def head(&block)
|
21
|
-
@in_header = true
|
22
|
-
@in_body = false
|
23
|
-
result = tag.thead(&block)
|
24
|
-
@in_header = false
|
25
|
-
result
|
26
|
-
end
|
27
|
-
|
28
|
-
def body(&block)
|
29
|
-
@in_header = false
|
30
|
-
@in_body = true
|
31
|
-
result = tag.tbody(class: "divide-y divide-gray-200 bg-white", &block)
|
32
|
-
@in_body = false
|
33
|
-
result
|
34
|
-
end
|
35
|
-
|
36
|
-
def tr(&block)
|
37
|
-
@current_row_cells = []
|
38
|
-
|
39
|
-
# Collect all cells first
|
40
|
-
yield if block_given?
|
41
|
-
|
42
|
-
# Now render each cell with proper first/last detection
|
43
|
-
rendered_cells = @current_row_cells.map.with_index do |cell, index|
|
44
|
-
is_first = index == 0
|
45
|
-
is_last = index == @current_row_cells.length - 1
|
46
|
-
|
47
|
-
if cell[:type] == :th
|
48
|
-
render_th(cell, is_first, is_last)
|
49
|
-
else
|
50
|
-
render_td(cell, is_first, is_last)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
result = tag.tr do
|
55
|
-
@template.safe_join(rendered_cells)
|
56
|
-
end
|
57
|
-
|
58
|
-
@current_row_cells = []
|
59
|
-
result
|
60
|
-
end
|
61
|
-
|
62
|
-
def th(scope: "col", align: :left, **options, &block)
|
63
|
-
content = capture(&block) if block_given?
|
64
|
-
|
65
|
-
# Store cell data for later processing in tr
|
66
|
-
cell = { type: :th, scope: scope, align: align, options: options, content: content }
|
67
|
-
@current_row_cells << cell
|
68
|
-
|
69
|
-
# Return empty string for now, actual rendering happens in tr
|
70
|
-
""
|
71
|
-
end
|
72
|
-
|
73
|
-
def td(align: :left, **options, &block)
|
74
|
-
content = capture(&block) if block_given?
|
75
|
-
|
76
|
-
# Store cell data for later processing in tr
|
77
|
-
cell = { type: :td, align: align, options: options, content: content }
|
78
|
-
@current_row_cells << cell
|
79
|
-
|
80
|
-
# Return empty string for now, actual rendering happens in tr
|
81
|
-
""
|
82
|
-
end
|
83
|
-
|
84
|
-
|
85
|
-
def empty_state(title: "No records found", icon: "heroicons/outline/document", colspan: nil, &block)
|
86
|
-
content = if block_given?
|
87
|
-
capture(&block)
|
88
|
-
else
|
89
|
-
tag.div(class: "text-center py-8") do
|
90
|
-
icon_content = @template.svg_icon(icon, class: "mx-auto h-12 w-12 text-gray-400")
|
91
|
-
|
92
|
-
icon_content + tag.p(title, class: "mt-2 text-sm font-medium text-gray-900") +
|
93
|
-
tag.p("Get started by creating a new record.", class: "mt-1 text-sm text-gray-500")
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
tr do
|
98
|
-
td(colspan: colspan, class: "text-center py-8 text-gray-500") do
|
99
|
-
content
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
private
|
105
|
-
|
106
|
-
def tag
|
107
|
-
@template.tag
|
108
|
-
end
|
109
|
-
|
110
|
-
def capture(*args, &block)
|
111
|
-
@template.capture(*args, &block)
|
112
|
-
end
|
113
|
-
|
114
|
-
def render_th(cell, is_first, is_last)
|
115
|
-
align_class = alignment_class(cell[:align])
|
116
|
-
|
117
|
-
if is_first
|
118
|
-
full_class = "py-3.5 pr-3 #{align_class} text-sm font-semibold text-gray-900 #{cell[:options][:class] || ""}".strip
|
119
|
-
elsif is_last
|
120
|
-
full_class = "relative py-3.5 #{align_class} text-sm font-semibold text-gray-900 #{cell[:options][:class] || ""}".strip
|
121
|
-
else
|
122
|
-
full_class = "pl-3 pr-3 py-3.5 #{align_class} text-sm font-semibold text-gray-900 #{cell[:options][:class] || ""}".strip
|
123
|
-
end
|
124
|
-
|
125
|
-
options = cell[:options].except(:class)
|
126
|
-
tag.th(cell[:content], scope: cell[:scope], class: full_class, **options)
|
127
|
-
end
|
128
|
-
|
129
|
-
def render_td(cell, is_first, is_last)
|
130
|
-
align_class = alignment_class(cell[:align])
|
131
|
-
|
132
|
-
if is_first
|
133
|
-
full_class = "py-4 pr-3 #{align_class} text-sm font-medium whitespace-nowrap text-gray-900 #{cell[:options][:class] || ""}".strip
|
134
|
-
elsif is_last
|
135
|
-
full_class = "relative py-4 #{align_class} text-sm font-medium whitespace-nowrap #{cell[:options][:class] || ""}".strip
|
136
|
-
else
|
137
|
-
full_class = "pl-3 pr-3 py-4 #{align_class} text-sm whitespace-nowrap text-gray-500 #{cell[:options][:class] || ""}".strip
|
138
|
-
end
|
139
|
-
|
140
|
-
options = cell[:options].except(:class)
|
141
|
-
tag.td(cell[:content], class: full_class, **options)
|
142
|
-
end
|
143
|
-
|
144
|
-
def alignment_class(align)
|
145
|
-
case align.to_sym
|
146
|
-
when :left
|
147
|
-
"text-left"
|
148
|
-
when :center
|
149
|
-
"text-center"
|
150
|
-
when :right
|
151
|
-
"text-right"
|
152
|
-
else
|
153
|
-
"text-left"
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|