tramway 0.5.5.1 → 0.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e2e7bd75d61196a4ba4302fe3c05d5dfce6928a35ea0d97022b9170ce911ca8
4
- data.tar.gz: 1b89b1fb5a18ae6d28c8afb1b8a1d94da832f0855c1acf1f5ab4f9fb0f1d4bd7
3
+ metadata.gz: ff761d41cd4748bf3d7e1451825da24764f69077b842e92f7be6baf0f14dff55
4
+ data.tar.gz: d9c3b25519ab3eb4dfe9c7d2e26d8dffb339a2743b6c5c494495bd4c5b71fc6c
5
5
  SHA512:
6
- metadata.gz: 4565144363a3419833bb267231fc403ff49c1da50caa3ee4ec936d6a2245fc2ddf89ab111af33cc7a5759cd9bc51d90cc456e5108acc78b73e99ca7ea5107158
7
- data.tar.gz: a83591d638a439dcd659474cfd50b73f9f292bff11fd2e18987c821df25888a9de4ae68d16fb2d7048eb36949869350339b8c3104ffaa71f92f97042d2a84ba9
6
+ metadata.gz: bb0c9c5121dc9a8213a0011c07265b2c42a486218966725df559c31f48b1f1e0cbbb50dc7fd10ddaac13f00a14d55ae57be42e121a1c1d44b1560822425f54af
7
+ data.tar.gz: 4488ab5046c8fee6150ee80459df3859f0a2d8b62948cfb91af93052dce2f0788aa067dde8261c9df0708ad31c853c522adc65c91c907cc71b4418c17bfc4244
data/README.md CHANGED
@@ -29,17 +29,18 @@ Add this line to your application's Gemfile:
29
29
 
30
30
  ```ruby
31
31
  gem "tramway"
32
- gem "haml-rails"
33
- gem "kaminari"
34
- gem "view_component"
35
32
  ```
36
33
 
37
- OR
34
+ Then install Tramway and its dependencies:
38
35
 
39
36
  ```shell
40
- bundle add tramway view_component kaminari view_component
37
+ bundle install
38
+ bin/rails g tramway:install
41
39
  ```
42
40
 
41
+ The install generator adds the required gems (`haml-rails`, `kaminari`, `view_component`, and `dry-initializer`) to your
42
+ application's Gemfile—if they are not present—and appends the Tailwind safelist configuration Tramway ships with.
43
+
43
44
  ## Getting Started
44
45
 
45
46
  **Step 1**
@@ -78,7 +79,9 @@ end
78
79
 
79
80
  **Step 4**
80
81
 
81
- Copy this [file](https://github.com/Purple-Magic/tramway/blob/main/config/tailwind.config.js) to config/tailwind.config.js
82
+ If you ran `bin/rails g tramway:install`, the Tailwind safelist was already appended to `config/tailwind.config.js`.
83
+ Otherwise, copy this [file](https://github.com/Purple-Magic/tramway/blob/main/config/tailwind.config.js) to
84
+ `config/tailwind.config.js`.
82
85
 
83
86
 
84
87
  **Step 5**
@@ -581,6 +584,7 @@ Tramway provides `tramway_form_for` helper that renders Tailwind-styled forms by
581
584
  ```ruby
582
585
  = tramway_form_for @user do |f|
583
586
  = f.text_field :text
587
+ = f.email_field :email
584
588
  = f.password_field :password
585
589
  = f.select :role, [:admin, :user]
586
590
  = f.multiselect :permissions, [['Create User', 'create_user'], ['Update user', 'update_user']]
@@ -592,12 +596,38 @@ will render [this](https://play.tailwindcss.com/xho3LfjKkK)
592
596
 
593
597
  Available form helpers:
594
598
  * text_field
599
+ * email_field
595
600
  * password_field
596
601
  * file_field
597
602
  * select
598
603
  * multiselect ([Stimulus-based](https://github.com/Purple-Magic/tramway#stimulus-based-inputs))
599
604
  * submit
600
605
 
606
+ **Examples**
607
+
608
+ 1. Sign In Form for `devise` authentication
609
+
610
+ *app/views/devise/sessions/new.html.haml*
611
+ ```haml
612
+ = tramway_form_for(resource, as: resource_name, url: session_path(resource_name), class: 'bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4') do |f|
613
+ = component 'forms/errors', record: resource
614
+
615
+ = f.text_field :email, placeholder: "Your email"
616
+ = f.password_field :password, placeholder: "Your password"
617
+
618
+ = f.submit "Sign In"
619
+ ```
620
+
621
+ 2. Sign In Form for Rails authorization
622
+
623
+ *app/views/sessions/new.html.haml*
624
+ ```haml
625
+ = form_with url: login_path, scope: :session, local: true, builder: Tailwinds::Form::Builder do |form|
626
+ = form.email_field :email
627
+ = form.password_field :password
628
+ = form.submit "Log in"
629
+ ```
630
+
601
631
  #### Stimulus-based inputs
602
632
 
603
633
  `tramway_form_for` provides Tailwind-styled Stimulus-based custom inputs.
@@ -0,0 +1,2 @@
1
+ %a.btn.btn-delete.bg-orange-500.hover:bg-orange-700.text-white.font-bold.py-2.px-4.rounded.ml-2{ onclick: "window.history.back(); return false;", href: '#' }
2
+ = t('actions.back')
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tailwinds
4
+ # Backbutton component
5
+ class BackButtonComponent < BaseComponent
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tailwinds
4
+ # Shared base component for Tailwinds components
5
+ class BaseComponent < Tramway::Component::Base
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ - if text.present?
2
+ - if method == :get
3
+ = link_to text, path, class: classes, **options.except(:class)
4
+ - else
5
+ = button_to text, path, method:, class: classes, **options.except(:class)
6
+ - else
7
+ - if method == :get
8
+ = link_to path, class: classes, **options.except(:class) do
9
+ = content
10
+ - else
11
+ = button_to path, method:, class: classes, **options.except(:class) do
12
+ = content
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tailwinds
4
+ # Default Tramway button
5
+ #
6
+ class ButtonComponent < BaseComponent
7
+ option :text, optional: true, default: -> {}
8
+ option :path
9
+ option :color, default: -> { :blue }
10
+ option :type, default: -> { :default }
11
+ option :size, default: -> { :middle }
12
+ option :method, optional: true, default: -> { :get }
13
+ option :options, optional: true, default: -> { {} }
14
+
15
+ def size_classes
16
+ case size
17
+ when :small
18
+ 'text-sm py-1 px-1'
19
+ when :middle
20
+ 'py-2 px-4'
21
+ end
22
+ end
23
+
24
+ def classes
25
+ (default_classes +
26
+ light_mode_classes +
27
+ dark_mode_classes +
28
+ (method == :get ? %w[px-1 h-fit] : ['cursor-pointer'])).compact.join(' ')
29
+ end
30
+
31
+ def default_classes
32
+ [
33
+ 'btn',
34
+ 'btn-primary',
35
+ 'font-bold',
36
+ 'rounded-sm',
37
+ 'flex',
38
+ 'flex-row',
39
+ size_classes.to_s,
40
+ options[:class].to_s
41
+ ]
42
+ end
43
+
44
+ def light_mode_classes
45
+ [
46
+ "bg-#{color}-500",
47
+ "hover:bg-#{color}-700",
48
+ 'text-white'
49
+ ]
50
+ end
51
+
52
+ def dark_mode_classes
53
+ [
54
+ "dark:bg-#{color}-600",
55
+ "dark:hover:bg-#{color}-800",
56
+ 'dark:text-gray-300'
57
+ ]
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,3 @@
1
+ .container.p-4.flex.align-center.justify-center.w-full.mx-auto.bg-gray-100.dark:bg-gray-900.text-gray-900.dark:text-white{ id: }
2
+ .flex.flex-col.justify-center.w-full.py-8.dark:text-white
3
+ = content
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tailwinds
4
+ module Containers
5
+ # Default page container in Tramway
6
+ class NarrowComponent < Tramway::Component::Base
7
+ option :id, optional: true, default: proc { SecureRandom.uuid }
8
+ end
9
+ end
10
+ end
@@ -11,34 +11,33 @@ module Tailwinds
11
11
  @form_size = options[:size] || options['size'] || :middle
12
12
  end
13
13
 
14
- def text_field(attribute, **options, &)
14
+ def common_field(component_name, input_method, attribute, **options, &)
15
15
  sanitized_options = sanitize_options(options)
16
16
 
17
- render(Tailwinds::Form::TextFieldComponent.new(
18
- input: input(:text_field),
17
+ component_class = "Tailwinds::Form::#{component_name.to_s.camelize}Component".constantize
18
+
19
+ render(component_class.new(
20
+ input: input(input_method),
19
21
  value: get_value(attribute, sanitized_options),
20
22
  **default_options(attribute, sanitized_options)
21
- ), &)
23
+ ),
24
+ &)
22
25
  end
23
26
 
24
- def number_field(attribute, **options, &)
25
- sanitized_options = sanitize_options(options)
27
+ def text_field(attribute, **, &)
28
+ common_field(:text_field, :text_field, attribute, **, &)
29
+ end
26
30
 
27
- render(Tailwinds::Form::NumberFieldComponent.new(
28
- input: input(:number_field),
29
- value: get_value(attribute, sanitized_options),
30
- **default_options(attribute, sanitized_options)
31
- ), &)
31
+ def email_field(attribute, **, &)
32
+ common_field(:text_field, :email_field, attribute, **, &)
32
33
  end
33
34
 
34
- def text_area(attribute, **options, &)
35
- sanitized_options = sanitize_options(options)
35
+ def number_field(attribute, **, &)
36
+ common_field(:number_field, :number_field, attribute, **, &)
37
+ end
36
38
 
37
- render(Tailwinds::Form::TextAreaComponent.new(
38
- input: input(:text_area),
39
- value: get_value(attribute, sanitized_options),
40
- **default_options(attribute, sanitized_options)
41
- ), &)
39
+ def text_area(attribute, **, &)
40
+ common_field(:text_area, :text_area, attribute, **, &)
42
41
  end
43
42
 
44
43
  def password_field(attribute, **options, &)
@@ -95,7 +94,7 @@ module Tailwinds
95
94
  end
96
95
 
97
96
  def get_value(attribute, options)
98
- options[:value] || object.public_send(attribute)
97
+ options[:value] || (object.present? ? object.public_send(attribute) : nil)
99
98
  end
100
99
 
101
100
  def default_options(attribute, options)
@@ -1,13 +1,25 @@
1
1
  module.exports = {
2
2
  safelist: [
3
+ // === Navbar ===
4
+ 'ml-4',
5
+
6
+ // === Custom table layout utilities ===
3
7
  'div-table',
4
8
  'div-table-row',
5
9
  'div-table-cell',
10
+ 'sm:text-base',
11
+ 'last:border-b-0',
12
+
13
+ // === Visibility and typography helpers ===
6
14
  'hidden',
15
+ 'xl:hidden',
7
16
  'text-xl',
8
17
  'text-4xl',
9
18
  'font-bold',
10
- 'xl:hidden',
19
+ 'text-right',
20
+
21
+ // === Grid templates used for configurable layouts ===
22
+ 'grid',
11
23
  'grid-cols-1',
12
24
  'grid-cols-2',
13
25
  'grid-cols-3',
@@ -18,44 +30,112 @@ module.exports = {
18
30
  'grid-cols-8',
19
31
  'grid-cols-9',
20
32
  'grid-cols-10',
21
- 'text-right',
22
- 'w-2/3',
33
+
34
+ // === Page container and alignment helpers ===
35
+ 'container',
36
+ 'mx-auto',
37
+ 'align-center',
38
+ 'justify-center',
39
+
40
+ // === Flexbox layout utilities ===
23
41
  'flex',
24
- 'bg-purple-700',
42
+ 'flex-col',
43
+ 'flex-wrap',
44
+ 'flex-row-reverse',
45
+ 'flex-auto',
46
+ 'flex-initial',
47
+ 'justify-between',
48
+ 'justify-end',
49
+ 'space-x-1',
50
+ 'items-center',
51
+
52
+ // === Responsive visibility helpers ===
53
+ 'sm:hidden',
54
+ 'sm:flex',
55
+
56
+ // === Sizing utilities ===
57
+ 'w-2/3',
58
+ 'w-full',
59
+ 'w-fit',
60
+ 'w-8',
61
+ 'min-w-96',
62
+ 'max-w-full',
63
+
64
+ // === Spacing utilities ===
65
+ 'p-4',
25
66
  'px-6',
26
- 'px-3',
27
67
  'px-4',
68
+ 'px-3',
69
+ 'py-8',
28
70
  'py-4',
29
71
  'py-2',
30
72
  'mb-2',
31
- 'dark:placeholder-gray-400',
73
+ 'mt-8',
74
+ 'mt-2',
75
+
76
+ // === Pagination styles ===
77
+ 'bg-white',
78
+ 'rounded-md',
79
+ 'hover:bg-purple-100',
80
+ 'hover:bg-gray-100',
81
+ 'hover:bg-gray-300',
82
+ 'hover:text-gray-800',
83
+
84
+ // === Dark mode pagination styles ===
32
85
  'dark:text-white',
33
86
  'dark:bg-gray-800',
34
- 'dark:bg-gray-900',
35
87
  'dark:hover:bg-gray-700',
88
+ 'dark:bg-gray-900',
36
89
  'dark:bg-gray-700',
37
90
  'dark:text-gray-400',
38
- 'dark:hover:bg-gray-700',
39
91
  'dark:hover:text-gray-400',
40
- 'ml-4',
41
- 'sm:text-base',
42
- 'sm:hidden',
43
- 'sm:flex',
44
- 'last:border-b-0',
45
- 'hover:bg-gray-100',
46
- 'hover:bg-gray-300',
47
- 'hover:text-gray-800',
48
- 'mt-8',
49
- 'justify-between',
50
- 'space-x-1',
51
- 'justify-end',
52
- 'mt-2',
92
+ 'dark:placeholder-gray-400',
93
+
94
+ // === Button and badge helpers ===
95
+ 'bg-purple-700',
96
+ 'rounded',
97
+ 'rounded-full',
98
+ 'rounded-t',
99
+ 'font-medium',
100
+ 'font-normal',
101
+ 'text-xs',
102
+
103
+ // === Form state helpers ===
53
104
  'disabled:bg-gray-100',
54
105
  'disabled:text-gray-400',
55
106
  'disabled:cursor-not-allowed',
56
- // pagination
57
- 'bg-white', 'rounded-md', 'hover:bg-purple-100', 'dark:text-white', 'dark:bg-gray-800', 'dark:hover:bg-gray-700',
58
- // multiselect styles
59
- 'absolute', 'shadow', 'top-11', 'z-40', 'w-full', 'lef-0', 'rounded', 'max-h-select', 'overflow-y-auto', 'cursor-pointer', 'rounded-t', 'border-b', 'hover:bg-teal-100', 'items-center', 'border-transparent', 'border-l-2,', 'relative', 'hover:border-teal-100', 'leading-6', 'bg-transparent', 'appearance-none', 'outline-none', 'h-full' , 'justify-center', 'm-1', 'font-medium', 'rounded-full', 'text-teal-700', 'bg-teal-100', 'border', 'border-teal-300', 'text-xs', 'font-normal', 'leading-none', 'max-w-full', 'flex-initial', 'flex-auto', 'flex-row-reverse',, 'flex-col', 'min-w-96', 'w-fit', 'flex-wrap', 'w-8', 'border-l',
107
+ 'mb-4',
108
+ 'bg-red-500',
109
+ 'hover:bg-red-700',
110
+
111
+ // === Multiselect dropdown positioning ===
112
+ 'absolute',
113
+ 'relative',
114
+ 'shadow',
115
+ 'top-11',
116
+ 'z-40',
117
+ 'left-0',
118
+ 'max-h-select',
119
+ 'overflow-y-auto',
120
+ 'cursor-pointer',
121
+
122
+ // === Multiselect option styling ===
123
+ 'border-b',
124
+ 'border',
125
+ 'border-l',
126
+ 'border-l-2',
127
+ 'border-transparent',
128
+ 'border-teal-300',
129
+ 'hover:border-teal-100',
130
+ 'bg-teal-100',
131
+ 'bg-transparent',
132
+ 'text-teal-700',
133
+ 'leading-6',
134
+ 'leading-none',
135
+ 'appearance-none',
136
+ 'outline-none',
137
+ 'h-full',
138
+ 'm-1',
139
+ 'hover:bg-teal-100',
60
140
  ],
61
141
  }
@@ -0,0 +1,133 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require 'fileutils'
5
+
6
+ module Tramway
7
+ module Generators
8
+ # Running `rails generate tramway:install` will invoke this generator
9
+ #
10
+ class InstallGenerator < Rails::Generators::Base
11
+ desc 'Installs Tramway dependencies and Tailwind safelist configuration.'
12
+
13
+ def ensure_dependencies
14
+ missing_dependencies = gem_dependencies.reject do |dependency|
15
+ gemfile_contains?(dependency[:name])
16
+ end
17
+
18
+ return if missing_dependencies.empty?
19
+
20
+ append_to_file 'Gemfile', <<~GEMS
21
+
22
+ # Tramway dependencies
23
+ #{missing_dependencies.pluck(:declaration).join("\n")}
24
+
25
+ GEMS
26
+ end
27
+
28
+ def ensure_tailwind_safelist
29
+ return create_tailwind_config unless File.exist?(tailwind_config_path)
30
+
31
+ source_entries = extract_safelist_entries(File.read(gem_tailwind_config_path))
32
+ target_content = File.read(tailwind_config_path)
33
+ target_entries = extract_safelist_entries(target_content)
34
+
35
+ missing_entries = source_entries - target_entries
36
+ return if missing_entries.empty?
37
+
38
+ File.write(tailwind_config_path, insert_entries(target_content, missing_entries))
39
+ end
40
+
41
+ def ensure_tailwind_application_stylesheet
42
+ path = tailwind_application_stylesheet_path
43
+ FileUtils.mkdir_p(File.dirname(path))
44
+
45
+ return create_file(path, "#{tailwind_css_import_line}\n") unless File.exist?(path)
46
+
47
+ content = File.read(path)
48
+ return if content.include?(tailwind_css_import_line)
49
+
50
+ File.open(path, 'a') do |file|
51
+ file.write("\n") unless content.empty? || content.end_with?("\n")
52
+ file.write("#{tailwind_css_import_line}\n")
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def gem_dependencies
59
+ @gem_dependencies ||= [
60
+ { name: 'haml-rails', declaration: 'gem "haml-rails"' },
61
+ { name: 'kaminari', declaration: 'gem "kaminari"' },
62
+ { name: 'view_component', declaration: 'gem "view_component"' },
63
+ { name: 'dry-initializer', declaration: "gem 'dry-initializer'" }
64
+ ]
65
+ end
66
+
67
+ def gemfile_path
68
+ @gemfile_path ||= File.join(destination_root, 'Gemfile')
69
+ end
70
+
71
+ def gemfile_contains?(name)
72
+ return false unless File.exist?(gemfile_path)
73
+
74
+ content = File.read(gemfile_path)
75
+ content.match?(/^\s*gem ['"]#{Regexp.escape(name)}['"]/)
76
+ end
77
+
78
+ def tailwind_config_path
79
+ @tailwind_config_path ||= File.join(destination_root, 'config/tailwind.config.js')
80
+ end
81
+
82
+ def gem_tailwind_config_path
83
+ @gem_tailwind_config_path ||= File.expand_path('../../../../config/tailwind.config.js', __dir__)
84
+ end
85
+
86
+ def tailwind_application_stylesheet_path
87
+ @tailwind_application_stylesheet_path ||= File.join(destination_root, 'app/assets/tailwind/application.css')
88
+ end
89
+
90
+ def tailwind_css_import_line
91
+ '@import "tailwindcss";'
92
+ end
93
+
94
+ def create_tailwind_config
95
+ create_file tailwind_config_path, File.read(gem_tailwind_config_path)
96
+ end
97
+
98
+ def extract_safelist_entries(content)
99
+ section = safelist_section(content)
100
+ return [] if section.nil?
101
+
102
+ section.scan(/'([^']+)'/).flatten.map(&:strip).reject(&:empty?).uniq
103
+ end
104
+
105
+ def safelist_section(content)
106
+ match = content.match(/safelist\s*:\s*\[(.*?)\]\s*,?/m)
107
+ match&.[](1)
108
+ end
109
+
110
+ def insert_entries(content, entries)
111
+ match = content.match(/safelist\s*:\s*\[(.*?)\](\s*,?)/m)
112
+ return content unless match
113
+
114
+ closing_index = match.begin(0) + match[0].rindex(']')
115
+ indentation = closing_indentation(content, closing_index)
116
+ formatted_entries = entries.map { |entry| "#{indentation}'#{entry}',\n" }.join
117
+
118
+ needs_leading_newline = content[closing_index - 1] != "\n"
119
+ insertion = String.new
120
+ insertion << "\n" if needs_leading_newline
121
+ insertion << formatted_entries
122
+
123
+ content.dup.insert(closing_index, insertion)
124
+ end
125
+
126
+ def closing_indentation(content, index)
127
+ line_start = content.rindex("\n", index - 1) || 0
128
+ line = content[line_start..index]
129
+ line[/^\s*/] || ' '
130
+ end
131
+ end
132
+ end
133
+ end
@@ -12,6 +12,45 @@ module Tramway
12
12
  &
13
13
  )
14
14
  end
15
+
16
+ def tramway_table(**options, &)
17
+ component 'tailwinds/table', options:, &
18
+ end
19
+
20
+ def tramway_row(**options, &)
21
+ component 'tailwinds/table/row',
22
+ cells: options.delete(:cells),
23
+ href: options.delete(:href),
24
+ options:,
25
+ &
26
+ end
27
+
28
+ def tramway_cell(&)
29
+ component 'tailwinds/table/cell', &
30
+ end
31
+
32
+ def tramway_button(path:, text: nil, method: :get, **options)
33
+ component 'tailwinds/button',
34
+ text:,
35
+ path:,
36
+ method:,
37
+ color: options.delete(:color),
38
+ type: options.delete(:type),
39
+ size: options.delete(:size),
40
+ options:
41
+ end
42
+
43
+ def tramway_back_button
44
+ component 'tailwinds/back_button'
45
+ end
46
+
47
+ def tramway_container(id: nil, &)
48
+ if id.present?
49
+ component 'tailwinds/containers/narrow', id: id, &
50
+ else
51
+ component 'tailwinds/containers/narrow', &
52
+ end
53
+ end
15
54
  end
16
55
  end
17
56
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tramway
4
- VERSION = '0.5.5.1'
4
+ VERSION = '0.6'
5
5
  end
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: 0.5.5.1
4
+ version: '0.6'
5
5
  platform: ruby
6
6
  authors:
7
7
  - kalashnikovisme
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2025-10-23 00:00:00.000000000 Z
12
+ date: 2025-10-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: anyway_config
@@ -143,6 +143,13 @@ files:
143
143
  - app/assets/javascripts/tramway/table_row_preview_controller.js
144
144
  - app/components/tailwind_component.html.haml
145
145
  - app/components/tailwind_component.rb
146
+ - app/components/tailwinds/back_button_component.html.haml
147
+ - app/components/tailwinds/back_button_component.rb
148
+ - app/components/tailwinds/base_component.rb
149
+ - app/components/tailwinds/button_component.html.haml
150
+ - app/components/tailwinds/button_component.rb
151
+ - app/components/tailwinds/containers/narrow_component.html.haml
152
+ - app/components/tailwinds/containers/narrow_component.rb
146
153
  - app/components/tailwinds/form/builder.rb
147
154
  - app/components/tailwinds/form/file_field_component.html.haml
148
155
  - app/components/tailwinds/form/file_field_component.rb
@@ -214,6 +221,7 @@ files:
214
221
  - app/views/tramway/layouts/application.html.haml
215
222
  - config/routes.rb
216
223
  - config/tailwind.config.js
224
+ - lib/generators/tramway/install/install_generator.rb
217
225
  - lib/kaminari/helpers/tag.rb
218
226
  - lib/rules/turbo_html_attributes_rules.rb
219
227
  - lib/tasks/tramway_tasks.rake