tramway 3.1.2.7 → 4.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 +79 -16
- data/app/assets/builds/tailwind.css +2 -0
- data/app/assets/javascripts/tramway/tramway.js +193 -5
- data/app/assets/stylesheets/font-awesome.css +2337 -0
- data/app/assets/tailwind/application.css +29 -0
- data/app/components/tramway/chat_component.html.haml +1 -1
- data/app/components/tramway/containers/main_component.rb +1 -3
- data/app/components/tramway/containers/narrow_component.rb +5 -4
- data/app/components/tramway/flash_component.html.haml +6 -0
- data/app/components/tramway/form/builder.rb +1 -2
- data/app/components/tramway/grid/card_component.html.haml +2 -0
- data/app/components/tramway/grid/card_component.rb +37 -0
- data/app/components/tramway/grid_component.html.haml +18 -0
- data/app/components/tramway/grid_component.rb +76 -0
- data/app/components/tramway/native_text_component.rb +1 -2
- data/app/components/tramway/nav/item_component.rb +4 -2
- data/app/components/tramway/navbar_component.html.haml +104 -110
- data/app/components/tramway/navbar_component.rb +84 -2
- data/app/components/tramway/table/cell_component.rb +9 -1
- data/app/components/tramway/table/header_component.rb +23 -2
- data/app/components/tramway/table/row_component.rb +27 -10
- data/app/components/tramway/table_component.rb +28 -1
- data/app/controllers/tramway/entities_controller.rb +6 -6
- data/app/views/tramway/layouts/application.html.haml +8 -6
- data/config/routes.rb +1 -2
- data/config/tailwind.config.js +57 -0
- data/lib/generators/tramway/install/font_awesome_helpers.rb +39 -0
- data/lib/generators/tramway/install/install_generator.rb +131 -65
- data/lib/generators/tramway/install/layout_helpers.rb +95 -0
- data/lib/tramway/engine.rb +12 -0
- data/lib/tramway/forms/validations.rb +1 -2
- data/lib/tramway/helpers/navbar_helper.rb +3 -1
- data/lib/tramway/helpers/table_helper.rb +27 -0
- data/lib/tramway/helpers/views_helper.rb +26 -2
- data/lib/tramway/version.rb +1 -1
- metadata +28 -4
|
@@ -2,12 +2,47 @@
|
|
|
2
2
|
|
|
3
3
|
require 'rails/generators'
|
|
4
4
|
require 'fileutils'
|
|
5
|
+
require_relative 'font_awesome_helpers'
|
|
6
|
+
require_relative 'layout_helpers'
|
|
5
7
|
|
|
6
8
|
module Tramway
|
|
7
9
|
module Generators
|
|
8
10
|
# nodoc
|
|
9
|
-
# rubocop:disable Metrics/ModuleLength
|
|
11
|
+
# rubocop:disable-next Metrics/ModuleLength
|
|
10
12
|
module InstallGeneratorHelpers
|
|
13
|
+
TAILWIND_SCROLLBAR_UTILITY = <<~CSS.chomp
|
|
14
|
+
@layer utilities {
|
|
15
|
+
.tramway-scrollbar {
|
|
16
|
+
scrollbar-width: thin;
|
|
17
|
+
scrollbar-color: rgba(82, 82, 91, 0.9) rgba(9, 9, 11, 0.92);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.tramway-scrollbar::-webkit-scrollbar {
|
|
21
|
+
width: 0.5rem;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.tramway-scrollbar::-webkit-scrollbar-track {
|
|
25
|
+
background: rgba(9, 9, 11, 0.92);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.tramway-scrollbar::-webkit-scrollbar-thumb {
|
|
29
|
+
border-radius: 9999px;
|
|
30
|
+
background: rgba(82, 82, 91, 0.9);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.tramway-scrollbar::-webkit-scrollbar-thumb:hover {
|
|
34
|
+
background: rgba(113, 113, 122, 0.95);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.tramway-scrollbar::-webkit-scrollbar-corner {
|
|
38
|
+
background: transparent;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
CSS
|
|
42
|
+
|
|
43
|
+
TAILWIND_APPLICATION_STYLESHEET_CONTENT =
|
|
44
|
+
"@import \"tailwindcss\";\n\n#{TAILWIND_SCROLLBAR_UTILITY}\n".freeze
|
|
45
|
+
|
|
11
46
|
private
|
|
12
47
|
|
|
13
48
|
def gem_dependencies
|
|
@@ -78,12 +113,13 @@ module Tramway
|
|
|
78
113
|
|
|
79
114
|
def stimulus_controller_imports
|
|
80
115
|
[
|
|
81
|
-
'import { TramwaySelect, TableRowPreview, UiCheckbox, Tooltip } from "@tramway/tramway"'
|
|
116
|
+
'import { Navbar, TramwaySelect, TableRowPreview, UiCheckbox, Tooltip } from "@tramway/tramway"'
|
|
82
117
|
]
|
|
83
118
|
end
|
|
84
119
|
|
|
85
120
|
def stimulus_controller_registrations
|
|
86
121
|
[
|
|
122
|
+
"application.register('tramway-navbar', Navbar)",
|
|
87
123
|
"application.register('tramway-select', TramwaySelect)",
|
|
88
124
|
"application.register('table-row-preview', TableRowPreview)",
|
|
89
125
|
"application.register('ui--checkbox', UiCheckbox)",
|
|
@@ -95,28 +131,6 @@ module Tramway
|
|
|
95
131
|
@agents_file_path ||= File.join(destination_root, 'AGENTS.md')
|
|
96
132
|
end
|
|
97
133
|
|
|
98
|
-
def application_layout_haml_path
|
|
99
|
-
@application_layout_haml_path ||= File.join(destination_root, 'app/views/layouts/application.html.haml')
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def application_layout_erb_path
|
|
103
|
-
@application_layout_erb_path ||= File.join(destination_root, 'app/views/layouts/application.html.erb')
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def trix_haml_tags
|
|
107
|
-
" = stylesheet_link_tag \"trix\", \"data-turbo-track\": \"reload\"\n " \
|
|
108
|
-
"= javascript_include_tag \"trix\", \"data-turbo-track\": \"reload\", defer: true\n"
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def trix_erb_tags
|
|
112
|
-
" <%= stylesheet_link_tag \"trix\", \"data-turbo-track\": \"reload\" %>\n " \
|
|
113
|
-
"<%= javascript_include_tag \"trix\", \"data-turbo-track\": \"reload\", defer: true %>\n"
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def trix_already_present?(content)
|
|
117
|
-
content.include?('stylesheet_link_tag "trix"') || content.include?("stylesheet_link_tag 'trix'")
|
|
118
|
-
end
|
|
119
|
-
|
|
120
134
|
def codex_agents_instruction
|
|
121
135
|
'If you are Codex, use the tramway-skill skill for Tramway/Rails work in this project. ' \
|
|
122
136
|
'If tramway-skill is not installed, install it from https://github.com/Purple-Magic/tramway-skill/.'
|
|
@@ -134,15 +148,16 @@ module Tramway
|
|
|
134
148
|
end
|
|
135
149
|
|
|
136
150
|
def safelist_section(content)
|
|
137
|
-
|
|
138
|
-
|
|
151
|
+
open_index, close_index = safelist_bracket_range(content)
|
|
152
|
+
return nil unless open_index
|
|
153
|
+
|
|
154
|
+
content[(open_index + 1)...close_index]
|
|
139
155
|
end
|
|
140
156
|
|
|
141
157
|
def insert_entries(content, entries)
|
|
142
|
-
|
|
143
|
-
return content unless
|
|
158
|
+
_open_index, closing_index = safelist_bracket_range(content)
|
|
159
|
+
return content unless closing_index
|
|
144
160
|
|
|
145
|
-
closing_index = match.begin(0) + match[0].rindex(']')
|
|
146
161
|
indentation = closing_indentation(content, closing_index)
|
|
147
162
|
formatted_entries = entries.map { |entry| "#{indentation}'#{entry}',\n" }.join
|
|
148
163
|
|
|
@@ -154,6 +169,33 @@ module Tramway
|
|
|
154
169
|
content.dup.insert(closing_index, insertion)
|
|
155
170
|
end
|
|
156
171
|
|
|
172
|
+
# Finds the `[`/`]` pair that delimits the `safelist` array, ignoring brackets that
|
|
173
|
+
# appear inside quoted entries (e.g. `'md:transition-[width]'`) since a naive regex
|
|
174
|
+
# would otherwise stop at the first `]`, wherever it occurs.
|
|
175
|
+
def safelist_bracket_range(content)
|
|
176
|
+
start_index = content =~ /safelist\s*:\s*\[/
|
|
177
|
+
return [nil, nil] unless start_index
|
|
178
|
+
|
|
179
|
+
open_index = content.index('[', start_index)
|
|
180
|
+
close_index = matching_bracket_index(content, open_index)
|
|
181
|
+
|
|
182
|
+
[open_index, close_index]
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def matching_bracket_index(content, open_index)
|
|
186
|
+
depth = 0
|
|
187
|
+
|
|
188
|
+
content[open_index..].to_enum(:scan, /'[^']*'|"[^"]*"|[\[\]]/).each do
|
|
189
|
+
token = Regexp.last_match[0]
|
|
190
|
+
next unless ['[', ']'].include?(token)
|
|
191
|
+
|
|
192
|
+
depth += token == '[' ? 1 : -1
|
|
193
|
+
return open_index + Regexp.last_match.end(0) - 1 if depth.zero?
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
nil
|
|
197
|
+
end
|
|
198
|
+
|
|
157
199
|
def closing_indentation(content, index)
|
|
158
200
|
line_start = content.rindex("\n", index - 1) || 0
|
|
159
201
|
line = content[line_start..index]
|
|
@@ -171,30 +213,39 @@ module Tramway
|
|
|
171
213
|
content.end_with?("\n") ? "\n" : "\n\n"
|
|
172
214
|
end
|
|
173
215
|
|
|
174
|
-
# rubocop:disable Metrics/MethodLength
|
|
175
216
|
def append_missing_imports(content)
|
|
176
217
|
content = remove_legacy_stimulus_imports(content)
|
|
218
|
+
content = normalize_tramway_stimulus_imports(content)
|
|
177
219
|
missing_imports = stimulus_controller_imports.reject { |line| content.include?(line) }
|
|
178
220
|
return content if missing_imports.empty?
|
|
179
221
|
|
|
180
222
|
import_lines = content.each_line.with_index.filter_map do |line, index|
|
|
181
223
|
index if line.lstrip.start_with?('import ')
|
|
182
224
|
end
|
|
183
|
-
|
|
225
|
+
insert_missing_imports(content, missing_imports.join("\n"), import_lines)
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def insert_missing_imports(content, imports, import_lines)
|
|
229
|
+
insertion = "#{imports}\n"
|
|
184
230
|
updated = content.dup
|
|
185
231
|
|
|
186
|
-
|
|
187
|
-
insertion_index = updated.lines[0..import_lines.max].join.length
|
|
188
|
-
updated.insert(insertion_index, insertion)
|
|
189
|
-
else
|
|
190
|
-
updated.prepend(insertion)
|
|
191
|
-
end
|
|
232
|
+
return updated.prepend(insertion) unless import_lines.any?
|
|
192
233
|
|
|
234
|
+
insertion_index = updated.lines[0..import_lines.max].join.length
|
|
235
|
+
updated.insert(insertion_index, insertion)
|
|
193
236
|
updated
|
|
194
237
|
end
|
|
195
|
-
|
|
238
|
+
|
|
239
|
+
def normalize_tramway_stimulus_imports(content)
|
|
240
|
+
tramway_import_lines = content.each_line.select { |line| tramway_stimulus_import_line?(line) }
|
|
241
|
+
return content unless tramway_import_lines.any?
|
|
242
|
+
return content if normalized_tramway_import_lines?(tramway_import_lines)
|
|
243
|
+
|
|
244
|
+
content.each_line.reject { |line| tramway_stimulus_import_line?(line) }.join
|
|
245
|
+
end
|
|
196
246
|
|
|
197
247
|
def append_missing_registrations(content)
|
|
248
|
+
content = normalize_tramway_stimulus_registrations(content)
|
|
198
249
|
missing_registrations = stimulus_controller_registrations.reject { |line| content.include?(line) }
|
|
199
250
|
return content if missing_registrations.empty?
|
|
200
251
|
|
|
@@ -221,6 +272,36 @@ module Tramway
|
|
|
221
272
|
content.each_line.reject { |line| legacy_imports.include?(line.strip) }.join
|
|
222
273
|
end
|
|
223
274
|
|
|
275
|
+
def tramway_stimulus_import_line?(line)
|
|
276
|
+
line.strip.match?(%r{^import \{.*\} from ["']@tramway/tramway["']$})
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def normalize_tramway_stimulus_registrations(content)
|
|
280
|
+
tramway_registration_lines = content.each_line.select { |line| tramway_stimulus_registration_line?(line) }
|
|
281
|
+
return content if tramway_registration_lines.sort == stimulus_controller_registrations.sort
|
|
282
|
+
return content unless tramway_registration_lines.any?
|
|
283
|
+
|
|
284
|
+
content.each_line.reject { |line| tramway_stimulus_registration_line?(line) }.join
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def tramway_stimulus_registration_line?(line)
|
|
288
|
+
tramway_registration_prefixes.any? { |prefix| line.strip.start_with?(prefix) }
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def normalized_tramway_import_lines?(tramway_import_lines)
|
|
292
|
+
tramway_import_lines.one? && tramway_import_lines.first.strip == stimulus_controller_imports.first
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def tramway_registration_prefixes
|
|
296
|
+
[
|
|
297
|
+
"application.register('tramway-navbar'",
|
|
298
|
+
"application.register('tramway-select'",
|
|
299
|
+
"application.register('table-row-preview'",
|
|
300
|
+
"application.register('ui--checkbox'",
|
|
301
|
+
"application.register('tramway-tooltip'"
|
|
302
|
+
]
|
|
303
|
+
end
|
|
304
|
+
|
|
224
305
|
def remove_legacy_importmap_pins(content)
|
|
225
306
|
content.each_line.reject { |line| legacy_importmap_pins.include?(line.strip) }.join
|
|
226
307
|
end
|
|
@@ -255,12 +336,12 @@ module Tramway
|
|
|
255
336
|
say_status(:warning, "Skipping AGENTS.md update: #{e.message}")
|
|
256
337
|
end
|
|
257
338
|
end
|
|
258
|
-
# rubocop:enable Metrics/ModuleLength
|
|
259
339
|
|
|
260
|
-
#
|
|
261
|
-
#
|
|
340
|
+
# Installs Tramway dependencies and app wiring for a host Rails app.
|
|
262
341
|
class InstallGenerator < Rails::Generators::Base
|
|
263
342
|
include InstallGeneratorHelpers
|
|
343
|
+
include InstallGeneratorFontAwesomeHelpers
|
|
344
|
+
include InstallGeneratorLayoutHelpers
|
|
264
345
|
|
|
265
346
|
desc 'Installs Tramway dependencies and Tailwind safelist configuration.'
|
|
266
347
|
|
|
@@ -310,15 +391,14 @@ module Tramway
|
|
|
310
391
|
path = tailwind_application_stylesheet_path
|
|
311
392
|
FileUtils.mkdir_p(File.dirname(path))
|
|
312
393
|
|
|
313
|
-
return create_file(path,
|
|
394
|
+
return create_file(path, TAILWIND_APPLICATION_STYLESHEET_CONTENT) unless File.exist?(path)
|
|
314
395
|
|
|
315
396
|
content = File.read(path)
|
|
316
|
-
return if content.include?(tailwind_css_import_line)
|
|
397
|
+
return if content.include?(tailwind_css_import_line) && content.include?(TAILWIND_SCROLLBAR_UTILITY)
|
|
317
398
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
end
|
|
399
|
+
updated = content.include?(tailwind_css_import_line) ? content : "#{content}\n#{tailwind_css_import_line}\n"
|
|
400
|
+
updated = "#{updated}\n#{TAILWIND_SCROLLBAR_UTILITY}\n" unless updated.include?(TAILWIND_SCROLLBAR_UTILITY)
|
|
401
|
+
File.write(path, updated)
|
|
322
402
|
end
|
|
323
403
|
|
|
324
404
|
def ensure_importmap_pin
|
|
@@ -348,30 +428,16 @@ module Tramway
|
|
|
348
428
|
|
|
349
429
|
def ensure_trix_in_application_layout
|
|
350
430
|
if File.exist?(application_layout_haml_path)
|
|
431
|
+
ensure_font_awesome_in_haml_layout
|
|
351
432
|
ensure_trix_in_haml_layout
|
|
352
433
|
elsif File.exist?(application_layout_erb_path)
|
|
434
|
+
ensure_font_awesome_in_erb_layout
|
|
353
435
|
ensure_trix_in_erb_layout
|
|
354
436
|
end
|
|
355
437
|
end
|
|
356
438
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
def ensure_trix_in_haml_layout
|
|
360
|
-
content = File.read(application_layout_haml_path)
|
|
361
|
-
return if trix_already_present?(content)
|
|
362
|
-
return unless content.match?(/^\s+%body/)
|
|
363
|
-
|
|
364
|
-
updated = content.sub(/^(\s+%body)/, "#{trix_haml_tags}\\1")
|
|
365
|
-
File.write(application_layout_haml_path, updated)
|
|
366
|
-
end
|
|
367
|
-
|
|
368
|
-
def ensure_trix_in_erb_layout
|
|
369
|
-
content = File.read(application_layout_erb_path)
|
|
370
|
-
return if trix_already_present?(content)
|
|
371
|
-
return unless content.include?('</head>')
|
|
372
|
-
|
|
373
|
-
updated = content.sub('</head>', "#{trix_erb_tags} </head>")
|
|
374
|
-
File.write(application_layout_erb_path, updated)
|
|
439
|
+
def ensure_navbar_sidebar_offset_in_application_layout
|
|
440
|
+
ensure_navbar_sidebar_offset
|
|
375
441
|
end
|
|
376
442
|
end
|
|
377
443
|
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tramway
|
|
4
|
+
module Generators
|
|
5
|
+
# Layout helpers for Tramway generator template updates.
|
|
6
|
+
module InstallGeneratorLayoutHelpers
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
def application_layout_haml_path
|
|
10
|
+
@application_layout_haml_path ||= File.join(destination_root, 'app/views/layouts/application.html.haml')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def application_layout_erb_path
|
|
14
|
+
@application_layout_erb_path ||= File.join(destination_root, 'app/views/layouts/application.html.erb')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def trix_haml_tags
|
|
18
|
+
" = stylesheet_link_tag \"trix\", \"data-turbo-track\": \"reload\"\n " \
|
|
19
|
+
"= javascript_include_tag \"trix\", \"data-turbo-track\": \"reload\", defer: true\n"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def trix_erb_tags
|
|
23
|
+
" <%= stylesheet_link_tag \"trix\", \"data-turbo-track\": \"reload\" %>\n " \
|
|
24
|
+
"<%= javascript_include_tag \"trix\", \"data-turbo-track\": \"reload\", defer: true %>\n"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def trix_already_present?(content)
|
|
28
|
+
content.include?('stylesheet_link_tag "trix"') || content.include?("stylesheet_link_tag 'trix'")
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def font_awesome_already_present?(content)
|
|
32
|
+
content.include?('stylesheet_link_tag "font-awesome"') ||
|
|
33
|
+
content.include?("stylesheet_link_tag 'font-awesome'")
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def navbar_sidebar_offset_class
|
|
37
|
+
'md:pl-72 transition-all duration-300 ease-in-out'
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def ensure_trix_in_haml_layout
|
|
41
|
+
content = File.read(application_layout_haml_path)
|
|
42
|
+
return if trix_already_present?(content)
|
|
43
|
+
return unless content.match?(/^\s+%body/)
|
|
44
|
+
|
|
45
|
+
updated = content.sub(/^(\s+%body)/, "#{trix_haml_tags}\\1")
|
|
46
|
+
File.write(application_layout_haml_path, updated)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def ensure_trix_in_erb_layout
|
|
50
|
+
content = File.read(application_layout_erb_path)
|
|
51
|
+
return if trix_already_present?(content)
|
|
52
|
+
return unless content.include?('</head>')
|
|
53
|
+
|
|
54
|
+
updated = content.sub('</head>', "#{trix_erb_tags} </head>")
|
|
55
|
+
File.write(application_layout_erb_path, updated)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def ensure_navbar_sidebar_offset
|
|
59
|
+
if File.exist?(application_layout_haml_path)
|
|
60
|
+
ensure_navbar_sidebar_offset_in_haml_layout
|
|
61
|
+
elsif File.exist?(application_layout_erb_path)
|
|
62
|
+
ensure_navbar_sidebar_offset_in_erb_layout
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def ensure_navbar_sidebar_offset_in_haml_layout
|
|
67
|
+
content = File.read(application_layout_haml_path)
|
|
68
|
+
return if content.include?(navbar_sidebar_offset_class)
|
|
69
|
+
return unless content.match?(/= tramway_main_container(?: class: '[^']*')? do/)
|
|
70
|
+
|
|
71
|
+
File.write(
|
|
72
|
+
application_layout_haml_path,
|
|
73
|
+
content.sub(
|
|
74
|
+
/= tramway_main_container(?: class: '[^']*')? do/,
|
|
75
|
+
"= tramway_main_container class: '#{navbar_sidebar_offset_class}' do"
|
|
76
|
+
)
|
|
77
|
+
)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def ensure_navbar_sidebar_offset_in_erb_layout
|
|
81
|
+
content = File.read(application_layout_erb_path)
|
|
82
|
+
return if content.include?(navbar_sidebar_offset_class)
|
|
83
|
+
return unless content.match?(/<%= tramway_main_container(?: class: '[^']*')? do %>/)
|
|
84
|
+
|
|
85
|
+
File.write(
|
|
86
|
+
application_layout_erb_path,
|
|
87
|
+
content.sub(
|
|
88
|
+
/<%= tramway_main_container(?: class: '[^']*')? do %>/,
|
|
89
|
+
"<%= tramway_main_container class: '#{navbar_sidebar_offset_class}' do %>"
|
|
90
|
+
)
|
|
91
|
+
)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
data/lib/tramway/engine.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'font-awesome-rails'
|
|
4
|
+
|
|
3
5
|
module Tramway
|
|
4
6
|
# Rails plugin is the Engine
|
|
5
7
|
#
|
|
@@ -17,8 +19,14 @@ module Tramway
|
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
initializer 'tramway.assets.precompile' do |app|
|
|
22
|
+
font_awesome_font_paths.each do |path|
|
|
23
|
+
path_string = path.to_s
|
|
24
|
+
app.config.assets.paths << path_string unless app.config.assets.paths.include?(path_string)
|
|
25
|
+
end
|
|
26
|
+
|
|
20
27
|
app.config.assets.precompile += %w[
|
|
21
28
|
tramway/tramway.js
|
|
29
|
+
font-awesome.css
|
|
22
30
|
]
|
|
23
31
|
end
|
|
24
32
|
|
|
@@ -88,6 +96,10 @@ module Tramway
|
|
|
88
96
|
end
|
|
89
97
|
end
|
|
90
98
|
|
|
99
|
+
def font_awesome_font_paths
|
|
100
|
+
[FontAwesome::Rails::Engine.root.join('app/assets/fonts')]
|
|
101
|
+
end
|
|
102
|
+
|
|
91
103
|
def configure_pagination
|
|
92
104
|
ActiveSupport.on_load(:action_controller) do
|
|
93
105
|
# Detecting tramway views path
|
|
@@ -16,11 +16,10 @@ module Tramway
|
|
|
16
16
|
def __initialize_validations(_subclass); end
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
# rubocop:disable Naming/PredicateMethod
|
|
19
|
+
# rubocop:disable-next Naming/PredicateMethod
|
|
20
20
|
def __apply_validations(_params)
|
|
21
21
|
valid?
|
|
22
22
|
end
|
|
23
|
-
# rubocop:enable Naming/PredicateMethod
|
|
24
23
|
end
|
|
25
24
|
end
|
|
26
25
|
end
|
|
@@ -6,11 +6,13 @@ module Tramway
|
|
|
6
6
|
module Helpers
|
|
7
7
|
# Provides navbar helpers for ActionView
|
|
8
8
|
module NavbarHelper
|
|
9
|
-
def tramway_navbar(with_entities: true, **options)
|
|
9
|
+
def tramway_navbar(with_entities: true, direction: :vertical, **options)
|
|
10
|
+
@tramway_navbar_direction = direction.presence&.to_sym || :vertical
|
|
10
11
|
initialize_navbar(with_entities:)
|
|
11
12
|
|
|
12
13
|
yield @navbar if block_given?
|
|
13
14
|
|
|
15
|
+
options[:direction] = direction if options[:direction].nil?
|
|
14
16
|
assign_navbar_items(options)
|
|
15
17
|
|
|
16
18
|
render_navbar_component(options)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tramway
|
|
4
|
+
module Helpers
|
|
5
|
+
# Provides size helpers for Tramway tables
|
|
6
|
+
module TableHelper
|
|
7
|
+
TABLE_SIZES = %i[small medium large].freeze
|
|
8
|
+
|
|
9
|
+
def tramway_table_size
|
|
10
|
+
context = tramway_table_context
|
|
11
|
+
return :medium unless context.respond_to?(:tramway_table_size)
|
|
12
|
+
|
|
13
|
+
TABLE_SIZES.include?(context.tramway_table_size) ? context.tramway_table_size : :medium
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def normalize_table_size(size)
|
|
17
|
+
TABLE_SIZES.include?(size) ? size : :medium
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def tramway_table_context
|
|
21
|
+
return __vc_original_view_context if respond_to?(:__vc_original_view_context)
|
|
22
|
+
|
|
23
|
+
view_context if respond_to?(:view_context)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'tramway/helpers/table_helper'
|
|
4
|
+
|
|
3
5
|
module Tramway
|
|
4
6
|
module Helpers
|
|
5
7
|
# Provides view-oriented helpers for ActionView
|
|
6
8
|
module ViewsHelper
|
|
7
9
|
include Tramway::Helpers::ComponentHelper
|
|
10
|
+
include Tramway::Helpers::TableHelper
|
|
8
11
|
|
|
9
12
|
FORM_SIZES = %i[small medium large].freeze
|
|
10
13
|
|
|
@@ -19,8 +22,16 @@ module Tramway
|
|
|
19
22
|
), &)
|
|
20
23
|
end
|
|
21
24
|
|
|
22
|
-
def tramway_table(**options, &)
|
|
23
|
-
component 'tramway/table', options:, &
|
|
25
|
+
def tramway_table(size: :medium, **options, &)
|
|
26
|
+
component 'tramway/table', size: normalize_table_size(size), options:, &
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def tramway_grid(rows:, columns:, outline: false, **options, &)
|
|
30
|
+
component 'tramway/grid', rows:, columns:, outline:, options:, &
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def tramway_card(size: [1, 1], **options, &)
|
|
34
|
+
component 'tramway/grid/card', size:, options:, &
|
|
24
35
|
end
|
|
25
36
|
|
|
26
37
|
def tramway_header(headers: nil, columns: nil, **options, &)
|
|
@@ -63,6 +74,8 @@ module Tramway
|
|
|
63
74
|
end
|
|
64
75
|
|
|
65
76
|
def tramway_main_container(**options, &)
|
|
77
|
+
options[:id] ||= 'tramway-main-container'
|
|
78
|
+
options[:class] = tramway_main_container_classes(options[:class])
|
|
66
79
|
component 'tramway/containers/main', options:, &
|
|
67
80
|
end
|
|
68
81
|
|
|
@@ -102,6 +115,17 @@ module Tramway
|
|
|
102
115
|
def normalize_form_size(size)
|
|
103
116
|
FORM_SIZES.include?(size) ? size : :medium
|
|
104
117
|
end
|
|
118
|
+
|
|
119
|
+
def tramway_main_container_classes(value)
|
|
120
|
+
classes = Array(value).flat_map { _1.to_s.split }
|
|
121
|
+
|
|
122
|
+
return classes.join(' ') if @tramway_navbar_direction.nil?
|
|
123
|
+
|
|
124
|
+
classes = classes.reject { _1.start_with?('md:pl-') || _1.start_with?('md:pr-') }
|
|
125
|
+
classes << 'md:pl-72' if @tramway_navbar_direction == :vertical
|
|
126
|
+
|
|
127
|
+
classes.join(' ')
|
|
128
|
+
end
|
|
105
129
|
end
|
|
106
130
|
end
|
|
107
131
|
end
|
data/lib/tramway/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tramway
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: '4.0'
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- kalashnikovisme
|
|
@@ -52,6 +52,20 @@ dependencies:
|
|
|
52
52
|
- - ">="
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
54
|
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: font-awesome-rails
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
55
69
|
- !ruby/object:Gem::Dependency
|
|
56
70
|
name: haml-rails
|
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -86,7 +100,7 @@ dependencies:
|
|
|
86
100
|
requirements:
|
|
87
101
|
- - ">="
|
|
88
102
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '
|
|
103
|
+
version: '8'
|
|
90
104
|
- - "<"
|
|
91
105
|
- !ruby/object:Gem::Version
|
|
92
106
|
version: '9'
|
|
@@ -96,7 +110,7 @@ dependencies:
|
|
|
96
110
|
requirements:
|
|
97
111
|
- - ">="
|
|
98
112
|
- !ruby/object:Gem::Version
|
|
99
|
-
version: '
|
|
113
|
+
version: '8'
|
|
100
114
|
- - "<"
|
|
101
115
|
- !ruby/object:Gem::Version
|
|
102
116
|
version: '9'
|
|
@@ -138,7 +152,10 @@ files:
|
|
|
138
152
|
- MIT-LICENSE
|
|
139
153
|
- README.md
|
|
140
154
|
- Rakefile
|
|
155
|
+
- app/assets/builds/tailwind.css
|
|
141
156
|
- app/assets/javascripts/tramway/tramway.js
|
|
157
|
+
- app/assets/stylesheets/font-awesome.css
|
|
158
|
+
- app/assets/tailwind/application.css
|
|
142
159
|
- app/components/tailwind_component.html.haml
|
|
143
160
|
- app/components/tailwind_component.rb
|
|
144
161
|
- app/components/tramway/actions_buttons_container_component.html.haml
|
|
@@ -207,6 +224,10 @@ files:
|
|
|
207
224
|
- app/components/tramway/form/tramway_select/selected_item_template_component.rb
|
|
208
225
|
- app/components/tramway/form/tramway_select_component.html.haml
|
|
209
226
|
- app/components/tramway/form/tramway_select_component.rb
|
|
227
|
+
- app/components/tramway/grid/card_component.html.haml
|
|
228
|
+
- app/components/tramway/grid/card_component.rb
|
|
229
|
+
- app/components/tramway/grid_component.html.haml
|
|
230
|
+
- app/components/tramway/grid_component.rb
|
|
210
231
|
- app/components/tramway/native_text_component.html.haml
|
|
211
232
|
- app/components/tramway/native_text_component.rb
|
|
212
233
|
- app/components/tramway/nav/item/button_component.html.haml
|
|
@@ -266,7 +287,9 @@ files:
|
|
|
266
287
|
- config/routes.rb
|
|
267
288
|
- config/tailwind.config.js
|
|
268
289
|
- docs/AGENTS.md
|
|
290
|
+
- lib/generators/tramway/install/font_awesome_helpers.rb
|
|
269
291
|
- lib/generators/tramway/install/install_generator.rb
|
|
292
|
+
- lib/generators/tramway/install/layout_helpers.rb
|
|
270
293
|
- lib/kaminari/helpers/tag.rb
|
|
271
294
|
- lib/rules/turbo_html_attributes_rules.rb
|
|
272
295
|
- lib/tasks/tramway_tasks.rake
|
|
@@ -296,6 +319,7 @@ files:
|
|
|
296
319
|
- lib/tramway/helpers/form_helper.rb
|
|
297
320
|
- lib/tramway/helpers/navbar_helper.rb
|
|
298
321
|
- lib/tramway/helpers/routes_helper.rb
|
|
322
|
+
- lib/tramway/helpers/table_helper.rb
|
|
299
323
|
- lib/tramway/helpers/views_helper.rb
|
|
300
324
|
- lib/tramway/navbar.rb
|
|
301
325
|
- lib/tramway/searchable.rb
|
|
@@ -326,7 +350,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
326
350
|
- !ruby/object:Gem::Version
|
|
327
351
|
version: '0'
|
|
328
352
|
requirements: []
|
|
329
|
-
rubygems_version: 4.0.
|
|
353
|
+
rubygems_version: 4.0.20
|
|
330
354
|
specification_version: 4
|
|
331
355
|
summary: Tramway Rails Engine
|
|
332
356
|
test_files: []
|