tramway 0.6 → 0.6.0.2

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: ff761d41cd4748bf3d7e1451825da24764f69077b842e92f7be6baf0f14dff55
4
- data.tar.gz: d9c3b25519ab3eb4dfe9c7d2e26d8dffb339a2743b6c5c494495bd4c5b71fc6c
3
+ metadata.gz: c3ac70ce33de0d7c3fbfd61650ff031137d8961713e9db94b93f0758ef2eba32
4
+ data.tar.gz: c8853c8169ac8821acafb3d47de20112400bd0e2d3e4c6390c3aec61917978a1
5
5
  SHA512:
6
- metadata.gz: bb0c9c5121dc9a8213a0011c07265b2c42a486218966725df559c31f48b1f1e0cbbb50dc7fd10ddaac13f00a14d55ae57be42e121a1c1d44b1560822425f54af
7
- data.tar.gz: 4488ab5046c8fee6150ee80459df3859f0a2d8b62948cfb91af93052dce2f0788aa067dde8261c9df0708ad31c853c522adc65c91c907cc71b4418c17bfc4244
6
+ metadata.gz: 485ff69148ae02c0967fa8d5bb75674b10a515a88c195ab86c7d6346b3710594bc3fb710e7d861d40f29287998c6f9a95ff2ddc63f4c0a14a8c69381179d12d6
7
+ data.tar.gz: ea7258f63f8adab1936e0f71e6a554857a8b650e3fb9182fe481a885a1823dee3ef5008280a849af141cffcfc10ed9324e9c01fd27106097df1af5938d6e57a4
data/README.md CHANGED
@@ -133,13 +133,56 @@ Tramway Entity supports several options that are used in different features.
133
133
  ```ruby
134
134
  Tramway.configure do |config|
135
135
  config.entities = [
136
- { name: :user, route: { namespace: :admin } }, # `admin_users_path` link in the Tramway Navbar
137
- { name: :podcast, route: { route_method: :shows } }, # `shows_path` link in the Tramway Navbar
138
- { name: :episodes, route: { namespace: :podcasts, route_method: :episodes } }, # `podcasts_episodes_path` link in the Tramway Navbar
136
+ {
137
+ name: :user,
138
+ route: { namespace: :admin }
139
+ }, # `/admin/users` link in the Tramway Navbar
140
+ {
141
+ name: :episodes,
142
+ route: {
143
+ namespace: :podcasts,
144
+ route_method: :episodes
145
+ }
146
+ }, # `/podcasts/episodes` link in the Tramway Navbar
139
147
  ]
140
148
  end
141
149
  ```
142
150
 
151
+ **scope**
152
+
153
+ By default, Tramway lists all records for an entity on the index page. You can narrow the records displayed by providing a
154
+ `scope`. When set, Tramway will call the named scope on the entity before rendering the index view.
155
+
156
+ *config/initializers/tramway.rb*
157
+ ```ruby
158
+ Tramway.configure do |config|
159
+ config.entities = [
160
+ {
161
+ name: :campaign,
162
+ route: { namespace: :admin },
163
+ pages: [
164
+ {
165
+ action: :index,
166
+ scope: :active
167
+ }
168
+ ]
169
+ }
170
+ ]
171
+ end
172
+ ```
173
+
174
+ In this example, the `Campaign` entity will display only records returned by the `active` scope on its index page, while all
175
+ other pages continue to show every record unless another scope is specified.
176
+
177
+ **route_helper**
178
+
179
+ To get routes Tramway generated just Tramway::Engine.
180
+
181
+ ```ruby
182
+ Tramway::Engine.routes.url_helpers.users_path => '/admin/users'
183
+ Tramway::Engine.routes.url_helpers.podcasts_episodes_path => '/podcasts/episodes'
184
+ ```
185
+
143
186
  ### Tramway Decorators
144
187
 
145
188
  Tramway provides convenient decorators for your objects. **NOTE:** This is not the decorator pattern in its usual representation.
@@ -455,15 +498,19 @@ tramway_navbar title: 'Purple Magic', background: { color: :red, intensity: 500
455
498
  end
456
499
  ```
457
500
 
458
- # Haml example
501
+ # ERB example
502
+
503
+ ```erb
504
+ <%= tramway_navbar title: 'Purple Magic', background: { color: :red, intensity: 500 } do |nav| %>
505
+ <% nav.left do %>
506
+ <%= nav.item 'Users', '/users' %>
507
+ <%= nav.item 'Podcasts', '/podcasts' %>
508
+ <% end %>
459
509
 
460
- ```haml
461
- = tramway_navbar title: 'Purple Magic', background: { color: :red, intensity: 500 } do |nav|
462
- - nav.left do
463
- - nav.item 'Users', '/users'
464
- - nav.item 'Podcasts', '/podcasts'
465
- - nav.right do
466
- - nav.item 'Sign out', '/users/sessions', method: :delete, confirm: 'Wanna quit?'
510
+ <% nav.right do %>
511
+ <%= nav.item 'Sign out', '/users/sessions', method: :delete, confirm: 'Wanna quit?' %>
512
+ <% end %>
513
+ <% end %>
467
514
  ```
468
515
 
469
516
  will render [this](https://play.tailwindcss.com/UZPTCudFw5)
@@ -485,13 +532,16 @@ with_entities: Show Tramway Entities index page links to navbar. Default: true
485
532
 
486
533
  In case you want to hide entity links you can pass `with_entities: false`.
487
534
 
488
- ```haml
489
- - if current_user.present?
490
- = tramway_navbar title: 'WaiWai' do |nav|
491
- - nav.left do
492
- - nav.item 'Board', admin_board_path
493
- - else
494
- = tramway_navbar title: 'WaiWai', with_entities: false
535
+ ```erb
536
+ <% if current_user.present? %>
537
+ <%= tramway_navbar title: 'WaiWai' do |nav| %>
538
+ <% nav.left do %>
539
+ <%= nav.item 'Board', admin_board_path %>
540
+ <% end %>
541
+ <% end %>
542
+ <% else %>
543
+ <%= tramway_navbar title: 'WaiWai', with_entities: false %>
544
+ <% end %>
495
545
  ```
496
546
 
497
547
  #### nav.left and nav.right
@@ -529,31 +579,43 @@ end
529
579
 
530
580
  ### Tramway Table Component
531
581
 
532
- Tramway provides a responsive, tailwind-styled table with light and dark themes.
582
+ Tramway provides a responsive, tailwind-styled table with light and dark themes. Use the `tramway_table`, `tramway_row`, and
583
+ `tramway_cell` helpers to build tables with readable ERB templates while still leveraging the underlying ViewComponent
584
+ implementations.
533
585
 
534
- ```haml
535
- = component 'tailwinds/table' do
536
- = component 'tailwinds/table/header', headers: ['Column 1', 'Column 2']
537
- = component 'tailwinds/table/row' do
538
- = component 'tailwinds/table/cell' do
586
+ ```erb
587
+ <%= tramway_table do %>
588
+ <%= tramway_header headers: ['Column 1', 'Column 2'] %>
589
+
590
+ <%= tramway_row do %>
591
+ <%= tramway_cell do %>
539
592
  Something
540
- = component 'tailwinds/table/cell' do
593
+ <% end %>
594
+ <%= tramway_cell do %>
541
595
  Another
596
+ <% end %>
597
+ <% end %>
598
+ <% end %>
542
599
  ```
543
600
 
544
- `Tailwinds::TableComponent` accepts an optional `options` hash that is merged into the outer `.div-table` element. The hash is
545
- forwarded as HTML attributes, so you can pass things like `id`, `data` attributes, or additional classes. If you do not supply
546
- your own width utility (e.g. a class that starts with `w-`), the component automatically appends `w-full` to keep the table
547
- responsive. This allows you to extend the default styling without losing the sensible defaults provided by the component.
601
+ `tramway_table` accepts the same optional `options` hash as `Tailwinds::TableComponent`. The hash is forwarded as HTML
602
+ attributes, so you can pass things like `id`, `data` attributes, or additional classes. If you do not supply your own width
603
+ utility (e.g. a class that starts with `w-`), the component automatically appends `w-full` to keep the table responsive. This
604
+ allows you to extend the default styling without losing the sensible defaults provided by the component.
605
+
606
+ ```erb
607
+ <%= tramway_table class: 'max-w-3xl border border-gray-200', data: { controller: 'table' } do %>
608
+ <%= tramway_header', headers: ['Name', 'Email'] %>
548
609
 
549
- ```haml
550
- = component 'tailwinds/table', options: { class: 'max-w-3xl border border-gray-200', data: { controller: 'table' } } do
551
- = component 'tailwinds/table/header', headers: ['Name', 'Email']
552
- = component 'tailwinds/table/row' do
553
- = component 'tailwinds/table/cell' do
554
- = user.name
555
- = component 'tailwinds/table/cell' do
556
- = user.email
610
+ <%= tramway_row do %>
611
+ <%= tramway_cell do %>
612
+ <%= user.name %>
613
+ <% end %>
614
+ <%= tramway_cell do %>
615
+ <%= user.email %>
616
+ <% end %>
617
+ <% end %>
618
+ <% end %>
557
619
  ```
558
620
 
559
621
  When you render a header you can either pass the `headers:` array, as in the examples above, or render custom header content in
@@ -561,18 +623,48 @@ the block. `Tailwinds::Table::HeaderComponent` uses the length of the `headers`
561
623
  If you omit the array and provide custom content, pass the `columns:` argument so the component knows how many grid columns to
562
624
  generate.
563
625
 
564
- ```haml
565
- = component 'tailwinds/table/header', columns: 4 do
566
- = component 'tailwinds/table/cell' do
626
+ ```erb
627
+ <%= component 'tailwinds/table/header', columns: 4 do %>
628
+ <%= tramway_cell do %>
567
629
  Custom header cell
568
- = component 'tailwinds/table/cell' do
630
+ <% end %>
631
+ <%= tramway_cell do %>
569
632
  Another header cell
570
- / ...
633
+ <% end %>
634
+ <!-- ... -->
635
+ <% end %>
571
636
  ```
572
637
 
573
638
  With this approach you control the header layout while still benefiting from the default Tailwind grid classes that the header
574
639
  component applies.
575
640
 
641
+ ### Tramway Buttons and Containers
642
+
643
+ Tramway ships with helpers for common UI patterns built on top of Tailwind components.
644
+
645
+ * `tramway_button` renders a button-styled link and accepts `path`, optional `text`, HTTP `method`, and styling options such as
646
+ `color`, `type`, and `size`. All additional keyword arguments are forwarded to the underlying component as HTML attributes.
647
+
648
+ ```erb
649
+ <%= tramway_button path: user_path(user), text: 'View profile', color: :emerald, data: { turbo: false } %>
650
+ ```
651
+
652
+ * `tramway_back_button` renders a standardized "Back" link.
653
+
654
+ ```erb
655
+ <%= tramway_back_button %>
656
+ ```
657
+
658
+ * `tramway_container` wraps content in a responsive, narrow layout container. Pass an `id` if you need to target the container
659
+ with JavaScript or CSS.
660
+
661
+ ```erb
662
+ <%= tramway_container id: 'user-settings' do %>
663
+ <h2 class="text-xl font-semibold">Settings</h2>
664
+ <p class="mt-2 text-gray-600">Update your preferences below.</p>
665
+ <% end %>
666
+ ```
667
+
576
668
  ### Tailwind-styled forms
577
669
 
578
670
  Tramway uses [Tailwind](https://tailwindcss.com/) by default. All UI helpers are implemented with [ViewComponent](https://github.com/viewcomponent/view_component).
@@ -581,15 +673,16 @@ Tramway uses [Tailwind](https://tailwindcss.com/) by default. All UI helpers are
581
673
 
582
674
  Tramway provides `tramway_form_for` helper that renders Tailwind-styled forms by default.
583
675
 
584
- ```ruby
585
- = tramway_form_for @user do |f|
586
- = f.text_field :text
587
- = f.email_field :email
588
- = f.password_field :password
589
- = f.select :role, [:admin, :user]
590
- = f.multiselect :permissions, [['Create User', 'create_user'], ['Update user', 'update_user']]
591
- = f.file_field :file
592
- = f.submit "Create User"
676
+ ```erb
677
+ <%= tramway_form_for @user do |f| %>
678
+ <%= f.text_field :text %>
679
+ <%= f.email_field :email %>
680
+ <%= f.password_field :password %>
681
+ <%= f.select :role, [:admin, :user] %>
682
+ <%= f.multiselect :permissions, [['Create User', 'create_user'], ['Update user', 'update_user']] %>
683
+ <%= f.file_field :file %>
684
+ <%= f.submit 'Create User' %>
685
+ <% end %>
593
686
  ```
594
687
 
595
688
  will render [this](https://play.tailwindcss.com/xho3LfjKkK)
@@ -607,25 +700,27 @@ Available form helpers:
607
700
 
608
701
  1. Sign In Form for `devise` authentication
609
702
 
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
703
+ *app/views/devise/sessions/new.html.erb*
704
+ ```erb
705
+ <%= 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| %>
706
+ <%= component 'forms/errors', record: resource %>
614
707
 
615
- = f.text_field :email, placeholder: "Your email"
616
- = f.password_field :password, placeholder: "Your password"
708
+ <%= f.text_field :email, placeholder: 'Your email' %>
709
+ <%= f.password_field :password, placeholder: 'Your password' %>
617
710
 
618
- = f.submit "Sign In"
711
+ <%= f.submit 'Sign In' %>
712
+ <% end %>
619
713
  ```
620
714
 
621
715
  2. Sign In Form for Rails authorization
622
716
 
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"
717
+ *app/views/sessions/new.html.erb*
718
+ ```erb
719
+ <%= form_with url: login_path, scope: :session, local: true, builder: Tailwinds::Form::Builder do |form| %>
720
+ <%= form.email_field :email %>
721
+ <%= form.password_field :password %>
722
+ <%= form.submit 'Log in' %>
723
+ <% end %>
629
724
  ```
630
725
 
631
726
  #### Stimulus-based inputs
@@ -636,10 +731,11 @@ Available form helpers:
636
731
 
637
732
  In case you want to use tailwind-styled multiselect this way
638
733
 
639
- ```haml
640
- = tramway_form_for @user do |f|
641
- = f.multiselect :permissions, [['Create User', 'create_user'], ['Update user', 'update_user']]
642
- #- ...
734
+ ```erb
735
+ <%= tramway_form_for @user do |f| %>
736
+ <%= f.multiselect :permissions, [['Create User', 'create_user'], ['Update user', 'update_user']] %>
737
+ <%# ... %>
738
+ <% end %>
643
739
  ```
644
740
 
645
741
  you should add Tramway Multiselect Stimulus controller to your application.
@@ -663,9 +759,10 @@ application.register('multiselect', Multiselect) // register Multiselect control
663
759
 
664
760
  Use Stimulus `change` action with Tramway Multiselect
665
761
 
666
- ```ruby
667
- = tramway_form_for @user do |f|
668
- = f.multiselect :role, data: { action: 'change->user-form#updateForm' } # user-form is your Stimulus controller, updateForm is a method inside user-form Stimulus controller
762
+ ```erb
763
+ <%= tramway_form_for @user do |f| %>
764
+ <%= f.multiselect :role, data: { action: 'change->user-form#updateForm' } %>
765
+ <% end %>
669
766
  ```
670
767
 
671
768
  ### Tailwind-styled pagination for Kaminari
@@ -687,9 +784,9 @@ Tramway.configure do |config|
687
784
  end
688
785
  ```
689
786
 
690
- *app/views/users/index.html.haml*
691
- ```haml
692
- = paginate @users # it will render tailwind-styled pagination buttons by default
787
+ *app/views/users/index.html.erb*
788
+ ```erb
789
+ <%= paginate @users %> <%# it will render tailwind-styled pagination buttons by default %>
693
790
  ```
694
791
 
695
792
  Pagination buttons looks like [this](https://play.tailwindcss.com/mqgDS5l9oY)
@@ -710,11 +807,41 @@ user_2 = tramway_form User.first
710
807
  user_2.object #=> returns pure user object
711
808
  ```
712
809
 
810
+ ## Configuration
811
+
812
+ ### Custom layout
813
+
814
+ In case you wanna use a custom layout:
815
+
816
+ 1. Create a controller
817
+ 2. Set the layout there
818
+ 3. Set this controller as `application_controller` in Tramway initializer
819
+ 4. Reload your server
820
+
821
+ **Example**
822
+
823
+ *app/controllers/admin/application_controller.rb*
824
+ ```ruby
825
+ class Admin::ApplicationController < ApplicationController
826
+ layout 'admin/application'
827
+ end
828
+ ```
829
+
830
+ *config/initializers/tramway.rb*
831
+ ```ruby
832
+ Tramway.configure do |config|
833
+ config.application_controller = 'Admin::ApplicationController'
834
+ end
835
+ ```
836
+
713
837
  ## Articles
714
838
  * [Tramway on Rails](https://kalashnikovisme.medium.com/tramway-on-rails-32158c35ed68)
839
+ * [Tramway is the way to deal with little things for Rails developers](https://medium.com/@kalashnikovisme/tramway-is-the-way-to-deal-with-little-things-for-rails-developers-4f502172a18c)
715
840
  * [Delegating ActiveRecord methods to decorators in Rails](https://kalashnikovisme.medium.com/delegating-activerecord-methods-to-decorators-in-rails-4e4ec1c6b3a6)
716
841
  * [Behave as ActiveRecord. Why do we want objects to be AR lookalikes?](https://kalashnikovisme.medium.com/behave-as-activerecord-why-do-we-want-objects-to-be-ar-lookalikes-d494d692e1d3)
717
842
  * [Decorating associations in Rails with Tramway](https://kalashnikovisme.medium.com/decorating-associations-in-rails-with-tramway-b46a28392f9e)
843
+ * [Easy-to-use Tailwind-styled multi-select built with Stimulus](https://medium.com/@kalashnikovisme/easy-to-use-tailwind-styled-multi-select-built-with-stimulus-b3daa9e307aa)
844
+ *
718
845
 
719
846
  ## Contributing
720
847
 
@@ -17,12 +17,12 @@
17
17
  %p.text-center.mt-10
18
18
  You should fill class-level method `self.list_attributes` inside your
19
19
  = decorator
20
+ - else
21
+ = component 'tailwinds/table' do
22
+ = component 'tailwinds/table/header', headers: list_attributes.map { |attribute| @model_class.human_attribute_name(attribute) }
23
+ - @entities.each do |item|
24
+ = render 'tramway/entities/entity', entity: item
20
25
 
21
- = component 'tailwinds/table' do
22
- = component 'tailwinds/table/header', headers: list_attributes.map { |attribute| @model_class.human_attribute_name(attribute) }
23
- - @entities.each do |item|
24
- = render 'tramway/entities/entity', entity: item
25
-
26
- - if Tramway.config.pagination[:enabled]
27
- .flex.mt-4
28
- = paginate @entities, custom_path_method: "#{@model_class.model_name.plural}_path"
26
+ - if Tramway.config.pagination[:enabled]
27
+ .flex.mt-4
28
+ = paginate @entities, custom_path_method: "#{@model_class.model_name.plural}_path"
@@ -1 +1,2 @@
1
- = render 'tramway/entities/list'
1
+ = tramway_container do
2
+ = render 'tramway/entities/list'
@@ -17,6 +17,14 @@ module Tramway
17
17
  component 'tailwinds/table', options:, &
18
18
  end
19
19
 
20
+ def tramway_header(headers: nil, columns: nil, &)
21
+ component 'tailwinds/table/header',
22
+ headers:,
23
+ columns:,
24
+ options:,
25
+ &
26
+ end
27
+
20
28
  def tramway_row(**options, &)
21
29
  component 'tailwinds/table/row',
22
30
  cells: options.delete(:cells),
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tramway
4
- VERSION = '0.6'
4
+ VERSION = '0.6.0.2'
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.6'
4
+ version: 0.6.0.2
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-25 00:00:00.000000000 Z
12
+ date: 2025-10-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: anyway_config