tramway 0.5.5 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 21ffe76c2224bd46292479de272ccdb59f0095075043507af3dd6098d5559933
4
- data.tar.gz: 6547f3ac892439dddb165dbf7d8a06dcb90d8adb6f12b65d921cb277ebf7754a
3
+ metadata.gz: 7e2e7bd75d61196a4ba4302fe3c05d5dfce6928a35ea0d97022b9170ce911ca8
4
+ data.tar.gz: 1b89b1fb5a18ae6d28c8afb1b8a1d94da832f0855c1acf1f5ab4f9fb0f1d4bd7
5
5
  SHA512:
6
- metadata.gz: 93bdfec725bc98cb5ab5a045604fe00c6669eaf8d89eedb081e0750a4b1073fda7c7f99964a3e4b8bbfb4f668024ca9341f512c5fed77d17ea05eeb31de19f37
7
- data.tar.gz: 6d6d161386768b114e82e031888ce118383bfb377c6b5e1551d9f8b7300f077af50eb6cb2bff3a6d4523ab0f43bbc77b69b3af180ed4895d7b8c24558c1876a4
6
+ metadata.gz: 4565144363a3419833bb267231fc403ff49c1da50caa3ee4ec936d6a2245fc2ddf89ab111af33cc7a5759cd9bc51d90cc456e5108acc78b73e99ca7ea5107158
7
+ data.tar.gz: a83591d638a439dcd659474cfd50b73f9f292bff11fd2e18987c821df25888a9de4ae68d16fb2d7048eb36949869350339b8c3104ffaa71f92f97042d2a84ba9
data/README.md CHANGED
@@ -14,6 +14,16 @@ Unite Ruby on Rails brilliance. Streamline development with Tramway.
14
14
  * [Tailwind-styled pagination](https://github.com/Purple-Magic/tramway?tab=readme-ov-file#tailwind-styled-pagination-for-kaminari)
15
15
  * [Articles](https://github.com/Purple-Magic/tramway#usage)
16
16
 
17
+ ## Compatibility
18
+
19
+ Tramway is actively verified against the following Ruby and Rails versions.
20
+
21
+ | Ruby \ Rails | 7.1 | 7.2 | 8.0 | 8.1 |
22
+ | ------------- | --- | --- | --- | --- |
23
+ | 3.2 | ✅ | ✅ | ✅ | ✅ |
24
+ | 3.3 | ✅ | ✅ | ✅ | ✅ |
25
+ | 3.4 | ✅ | ✅ | ✅ | ✅ |
26
+
17
27
  ## Installation
18
28
  Add this line to your application's Gemfile:
19
29
 
@@ -528,6 +538,38 @@ Tramway provides a responsive, tailwind-styled table with light and dark themes.
528
538
  Another
529
539
  ```
530
540
 
541
+ `Tailwinds::TableComponent` accepts an optional `options` hash that is merged into the outer `.div-table` element. The hash is
542
+ forwarded as HTML attributes, so you can pass things like `id`, `data` attributes, or additional classes. If you do not supply
543
+ your own width utility (e.g. a class that starts with `w-`), the component automatically appends `w-full` to keep the table
544
+ responsive. This allows you to extend the default styling without losing the sensible defaults provided by the component.
545
+
546
+ ```haml
547
+ = component 'tailwinds/table', options: { class: 'max-w-3xl border border-gray-200', data: { controller: 'table' } } do
548
+ = component 'tailwinds/table/header', headers: ['Name', 'Email']
549
+ = component 'tailwinds/table/row' do
550
+ = component 'tailwinds/table/cell' do
551
+ = user.name
552
+ = component 'tailwinds/table/cell' do
553
+ = user.email
554
+ ```
555
+
556
+ When you render a header you can either pass the `headers:` array, as in the examples above, or render custom header content in
557
+ the block. `Tailwinds::Table::HeaderComponent` uses the length of the `headers` array to build the grid if the array is present.
558
+ If you omit the array and provide custom content, pass the `columns:` argument so the component knows how many grid columns to
559
+ generate.
560
+
561
+ ```haml
562
+ = component 'tailwinds/table/header', columns: 4 do
563
+ = component 'tailwinds/table/cell' do
564
+ Custom header cell
565
+ = component 'tailwinds/table/cell' do
566
+ Another header cell
567
+ / ...
568
+ ```
569
+
570
+ With this approach you control the header layout while still benefiting from the default Tailwind grid classes that the header
571
+ component applies.
572
+
531
573
  ### Tailwind-styled forms
532
574
 
533
575
  Tramway uses [Tailwind](https://tailwindcss.com/) by default. All UI helpers are implemented with [ViewComponent](https://github.com/viewcomponent/view_component).
@@ -99,13 +99,7 @@ module Tailwinds
99
99
  end
100
100
 
101
101
  def default_options(attribute, options)
102
- {
103
- attribute:,
104
- label: label_build(attribute, options),
105
- for: for_id(attribute),
106
- options:,
107
- size: form_size
108
- }
102
+ { attribute:, label: label_build(attribute, options), for: for_id(attribute), options:, size: form_size }
109
103
  end
110
104
 
111
105
  # :reek:UtilityFunction
@@ -1,8 +1,8 @@
1
1
  .mb-4
2
- - if @label
3
- - base_classes = 'inline-block bg-blue-500 hover:bg-blue-700 text-white font-bold rounded cursor-pointer mt-4 '
4
- - base_classes += 'dark:bg-blue-600 dark:hover:bg-blue-500'
5
- - classes = "#{size_class(:file_button)} #{base_classes}"
6
- %label{ for: @for, class: classes }
7
- = @label
2
+ - if @label
3
+ - base_classes = 'inline-block bg-blue-500 hover:bg-blue-700 text-white font-bold rounded cursor-pointer mt-4 '
4
+ - base_classes += 'dark:bg-blue-600 dark:hover:bg-blue-500'
5
+ - classes = "#{size_class(:file_button)} #{base_classes}"
6
+ %label{ for: @for, class: classes }
7
+ = @label
8
8
  = @input
@@ -2,11 +2,4 @@
2
2
  - base_classes = 'bg-transparent appearance-none outline-none h-full w-full text-gray-800 hidden '
3
3
  - base_classes += 'dark:text-white dark:placeholder-white'
4
4
  - classes = "#{@size_class} #{base_classes}"
5
- = @input.call(
6
- @attribute,
7
- @options.merge(
8
- placeholder: "{{placeholder}}",
9
- class: classes,
10
- data: { 'multiselect-target' => 'hiddenInput' }
11
- )
12
- )
5
+ = @input.call(@attribute, @options.merge(placeholder: "{{placeholder}}", class: classes, data: { 'multiselect-target' => 'hiddenInput' }))
@@ -12,26 +12,22 @@ module Tailwinds
12
12
  default_attributes = { role: :row }
13
13
 
14
14
  if href.present?
15
- klass = "#{options[:class] || ''} #{link_row_classes}"
16
-
17
- link_to(href, options.merge(class: klass, **default_attributes)) do
15
+ link_to(href, options.merge(class: "#{options[:class] || ''} #{link_row_classes}", **default_attributes)) do
18
16
  yield if block_given?
19
17
  end
20
18
  else
21
- tag.div(**options.merge(default_attributes)) do
19
+ tag.div(**options, **default_attributes) do
22
20
  yield if block_given?
23
21
  end
24
22
  end
25
23
  end
26
24
 
27
- # :reek:UtilityFunction { enabled: false }
28
25
  def desktop_row_classes(cells_count)
29
26
  [
30
27
  'div-table-row', 'grid', 'gap-4', 'bg-white', 'border-b', 'last:border-b-0', 'dark:bg-gray-800',
31
28
  'dark:border-gray-700', "grid-cols-#{cells_count}"
32
29
  ].join(' ')
33
30
  end
34
- # :reek:UtilityFunction { enabled: true }
35
31
 
36
32
  def link_row_classes
37
33
  'cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700'
@@ -11,11 +11,13 @@ module Tramway
11
11
  include Rails.application.routes.url_helpers
12
12
 
13
13
  def index
14
- @entities = if entity.page(:index).scope.present?
15
- model_class.public_send(entity.page(:index).scope)
16
- else
17
- model_class.order(id: :desc)
18
- end.page(params[:page])
14
+ if index_scope.present?
15
+ model_class.public_send(index_scope)
16
+ else
17
+ model_class.order(id: :desc)
18
+ end.page(params[:page]) => entities
19
+
20
+ @entities = entities
19
21
 
20
22
  @namespace = entity.route&.namespace
21
23
  end
@@ -29,5 +31,9 @@ module Tramway
29
31
  def entity
30
32
  @entity ||= Tramway.config.entities.find { |e| e.name == params[:entity][:name] }
31
33
  end
34
+
35
+ def index_scope
36
+ entity.page(:index).scope
37
+ end
32
38
  end
33
39
  end
data/config/routes.rb CHANGED
@@ -3,13 +3,13 @@
3
3
  Tramway::Engine.routes.draw do
4
4
  Tramway.config.entities.each do |entity|
5
5
  segments = entity.name.split('/')
6
- resource_name = segments.pop
6
+ resource_name = segments.pop
7
7
 
8
8
  define_resource = proc do
9
9
  resources resource_name.pluralize.to_sym,
10
- only: [:index],
11
- controller:'/tramway/entities',
12
- defaults: { entity: entity }
10
+ only: [:index],
11
+ controller: '/tramway/entities',
12
+ defaults: { entity: entity }
13
13
  end
14
14
 
15
15
  if segments.empty?
@@ -50,7 +50,7 @@ module Tramway
50
50
  end
51
51
 
52
52
  def method_missing(method_name, *args)
53
- if method_name.to_s.end_with?('=') && args.count == 1
53
+ if method_name.to_s.end_with?('=') && args.one?
54
54
  object.public_send(method_name, args.first)
55
55
  else
56
56
  super
@@ -40,7 +40,7 @@ module Tramway
40
40
  class << self
41
41
  def decorate_has_many_association(assoc, decorator_class: nil)
42
42
  return [] if assoc.empty?
43
-
43
+
44
44
  decorator_class ||= decorator(assoc.klass)
45
45
 
46
46
  decorator_class.decorate(assoc)
@@ -20,26 +20,19 @@ module Tramway
20
20
  end
21
21
 
22
22
  def decorator_class_name(object_or_array_or_class, namespace)
23
- klass = if Tramway::Decorators::CollectionDecorators.collection?(object_or_array_or_class)
24
- object_or_array_or_class.first.class
25
- elsif object_or_array_or_class.is_a?(Class)
26
- object_or_array_or_class
27
- else
28
- object_or_array_or_class.class
29
- end
23
+ if Tramway::Decorators::CollectionDecorators.collection?(object_or_array_or_class)
24
+ object_or_array_or_class.first.class
25
+ elsif object_or_array_or_class.is_a?(Class)
26
+ object_or_array_or_class
27
+ else
28
+ object_or_array_or_class.class
29
+ end => klass
30
30
 
31
31
  base_class_name = Tramway::Decorators::NameBuilder.default_decorator_class_name(klass)
32
32
 
33
- klass_name = namespace.present? ? "#{namespace.to_s.camelize}::#{base_class_name}" : base_class_name
34
-
35
- if klass_name.safe_constantize
36
- klass_name
37
- else
38
- raise NameError, "You should define #{klass_name} decorator class in app/decorators/ folder."
39
- end
33
+ build_klass_name(base_class_name, namespace)
40
34
  end
41
35
 
42
- # :reek:NilCheck { enabled: false }
43
36
  def raise_error_if_object_empty(object_or_array, decorator)
44
37
  return unless object_or_array.blank? && decorator.nil?
45
38
 
@@ -47,7 +40,16 @@ module Tramway
47
40
 
48
41
  raise ArgumentError, text
49
42
  end
50
- # :reek:NilCheck { enabled: true }
43
+
44
+ def build_klass_name(base_class_name, namespace)
45
+ klass_name = namespace.present? ? "#{namespace.to_s.camelize}::#{base_class_name}" : base_class_name
46
+
47
+ unless klass_name.safe_constantize
48
+ raise NameError, "You should define #{klass_name} decorator class in app/decorators/ folder."
49
+ end
50
+
51
+ klass_name
52
+ end
51
53
  end
52
54
  end
53
55
  end
@@ -10,21 +10,17 @@ module Tramway
10
10
  @properties << attribute
11
11
 
12
12
  define_method(attribute) do
13
- if object.respond_to?(attribute)
14
- object.public_send(attribute)
15
- else
16
- raise NoMethodError, "#{self.class}##{attribute} is not defined"
17
- end
13
+ raise NoMethodError, "#{self.class}##{attribute} is not defined" unless object.respond_to?(attribute)
14
+
15
+ object.public_send(attribute)
18
16
  end
19
17
 
20
18
  set_method = "#{attribute}="
21
19
 
22
20
  define_method(set_method) do |value|
23
- if object.respond_to?(set_method)
24
- object.public_send(set_method, value)
25
- else
26
- raise NoMethodError, "#{self.class}##{set_method} is not defined"
27
- end
21
+ raise NoMethodError, "#{self.class}##{set_method} is not defined" unless object.respond_to?(set_method)
22
+
23
+ object.public_send(set_method, value)
28
24
  end
29
25
  end
30
26
 
@@ -10,13 +10,13 @@ module Tramway
10
10
  @items = { left: [], right: [] }
11
11
  @filling = nil
12
12
 
13
- if with_entities
14
- entities = Tramway.config.entities
13
+ return unless with_entities
15
14
 
16
- return unless entities.any?
15
+ entities = Tramway.config.entities
17
16
 
18
- preset_left entities
19
- end
17
+ return unless entities.any?
18
+
19
+ preset_left entities
20
20
  end
21
21
 
22
22
  def left
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tramway
4
- VERSION = '0.5.5'
4
+ VERSION = '0.5.5.1'
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
4
+ version: 0.5.5.1
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-14 00:00:00.000000000 Z
12
+ date: 2025-10-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: anyway_config