tramway 2.2.4 → 2.2.5

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.
Files changed (23) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +7 -3
  3. data/app/assets/javascripts/tramway/multiselect_controller.js +7 -1
  4. data/app/components/tailwind_component.rb +3 -3
  5. data/app/components/tailwinds/form/multiselect/caret_component.html.haml +7 -0
  6. data/app/components/tailwinds/form/multiselect/caret_component.rb +19 -0
  7. data/app/components/tailwinds/form/multiselect/dropdown_container_component.rb +26 -0
  8. data/app/components/tailwinds/form/multiselect/{item_container.html.haml → item_container_component.html.haml} +1 -4
  9. data/app/components/tailwinds/form/multiselect/item_container_component.rb +24 -0
  10. data/app/components/tailwinds/form/multiselect/{select_as_input.rb → select_as_input_component.rb} +1 -1
  11. data/app/components/tailwinds/form/multiselect/selected_item_template_component.html.haml +6 -0
  12. data/app/components/tailwinds/form/multiselect/selected_item_template_component.rb +26 -0
  13. data/app/components/tailwinds/form/multiselect_component.html.haml +10 -7
  14. data/app/components/tailwinds/form/multiselect_component.rb +34 -38
  15. data/config/tailwind.config.js +19 -1
  16. data/lib/tramway/version.rb +1 -1
  17. metadata +11 -9
  18. data/app/components/tailwinds/form/multiselect/dropdown_container.rb +0 -17
  19. data/app/components/tailwinds/form/multiselect/item_container.rb +0 -30
  20. data/app/components/tailwinds/form/multiselect/selected_item_template.html.haml +0 -6
  21. data/app/components/tailwinds/form/multiselect/selected_item_template.rb +0 -17
  22. /data/app/components/tailwinds/form/multiselect/{dropdown_container.html.haml → dropdown_container_component.html.haml} +0 -0
  23. /data/app/components/tailwinds/form/multiselect/{select_as_input.html.haml → select_as_input_component.html.haml} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 16dea01fb21b124c9230e27238eb4d7f4f872d3e4348b9b16ca79e48e4ad1ac8
4
- data.tar.gz: 8dfbda56fba27bb45e93e8048823f8b32adce01a5f8e8412608e13c694022005
3
+ metadata.gz: cd9400e71d346fc1c334cf2f7d2a8a52847c0000957b675cc5bc6c38132a1bb9
4
+ data.tar.gz: 8a36f11fc6dec4e76241f150f8fe0d2d3f8bd187a5ff46f71b6e50cddb660479
5
5
  SHA512:
6
- metadata.gz: 64e58a748628c72a579964e6c604695a29711b28a673eae560922dc2dd5c179116767a2026e15a9d898dc773ac62ee92b3afc4c2b94c921933c1e8b1bac57260
7
- data.tar.gz: 83b5e8825a9ef8592ea244ab883e363136b9b77281b3c42ff5d256818e33a9330a683fb3074b1c902c27cf014a1f852a5f3a788f152d0af8a133648b1c4681fe
6
+ metadata.gz: f6e6ae7bc9326a651b59fce3c82d88c826f1cff4712248e0c7a0b1e7abd3033b47f91151d3f6d6007a1ba33ae5097455a48aeaf835e328a45edeb329ae8160d6
7
+ data.tar.gz: b546d9583c1c97b7d75797a145de2a522b4e5edd25d09add7cf3b106ac9c6bf89ae541d43667320a4f3adaafef9e7d961bc19f542595258ec5eaed8c698da12d
data/README.md CHANGED
@@ -656,7 +656,7 @@ end
656
656
 
657
657
  ### Form inheritance
658
658
 
659
- Tramway Form supports inheritance of `properties` and `normalizations`
659
+ Tramway Form supports inheritance of `properties`, `normalizations`, and `fields`.
660
660
 
661
661
  **Example**
662
662
 
@@ -665,6 +665,9 @@ class UserForm < TramwayForm
665
665
  properties :email, :password
666
666
 
667
667
  normalizes :email, with: ->(value) { value.strip.downcase }
668
+
669
+ fields email: :email,
670
+ password: :password
668
671
  end
669
672
 
670
673
  class AdminForm < UserForm
@@ -672,7 +675,8 @@ class AdminForm < UserForm
672
675
  end
673
676
 
674
677
  AdminForm.properties # returns [:email, :password, :permissions]
675
- AdminForm.normalizations # contains the normalization of :email
678
+ AdminForm.normalizations # contains the normalization of :email
679
+ AdminForm.fields # { email: :email, password: :password }
676
680
  ```
677
681
 
678
682
  ### Make flexible and extendable forms
@@ -1083,7 +1087,7 @@ eagerLoadControllersFrom("controllers", application)
1083
1087
  application.register('multiselect', Multiselect) // register Multiselect controller class as `multiselect` stimulus controller
1084
1088
  ```
1085
1089
 
1086
- Use Stimulus `change` action with Tramway Multiselect
1090
+ In case you need to use Stimulus `change` action with Tramway Multiselect
1087
1091
 
1088
1092
  ```erb
1089
1093
  <%= tramway_form_for @user do |f| %>
@@ -1,7 +1,7 @@
1
1
  import { Controller } from "@hotwired/stimulus"
2
2
 
3
3
  export default class Multiselect extends Controller {
4
- static targets = ["dropdown", "showSelectedArea", "hiddenInput"];
4
+ static targets = ["dropdown", "showSelectedArea", "hiddenInput", "caretDown", "caretUp"]
5
5
 
6
6
  static values = {
7
7
  items: Array,
@@ -79,6 +79,9 @@ export default class Multiselect extends Controller {
79
79
  if (this.dropdown()) {
80
80
  this.dropdown().addEventListener('click', event => event.stopPropagation());
81
81
  }
82
+
83
+ this.caretDownTarget.classList.add('hidden');
84
+ this.caretUpTarget.classList.remove('hidden');
82
85
  }
83
86
 
84
87
  dropdown() {
@@ -107,6 +110,9 @@ export default class Multiselect extends Controller {
107
110
  alert(`Controller not found: ${controllerName}`); // eslint-disable-line no-undef
108
111
  }
109
112
  }
113
+
114
+ this.caretDownTarget.classList.remove('hidden');
115
+ this.caretUpTarget.classList.add('hidden');
110
116
  }
111
117
 
112
118
  get template() {
@@ -18,21 +18,21 @@ class TailwindComponent < Tramway::BaseComponent
18
18
  select_input: 'text-sm px-2 py-1',
19
19
  file_button: 'text-sm px-3 py-1',
20
20
  submit_button: 'text-sm px-3 py-1',
21
- multiselect_input: 'text-sm px-2 py-1'
21
+ multiselect_input: 'text-sm px-2 py-1 h-10'
22
22
  },
23
23
  medium: {
24
24
  text_input: 'text-base px-3 py-2',
25
25
  select_input: 'text-base px-3 py-2',
26
26
  file_button: 'text-base px-4 py-2',
27
27
  submit_button: 'text-base px-4 py-2',
28
- multiselect_input: 'text-base px-3 py-2'
28
+ multiselect_input: 'text-base px-2 py-1 h-12'
29
29
  },
30
30
  large: {
31
31
  text_input: 'text-xl px-4 py-3',
32
32
  select_input: 'text-xl px-4 py-3',
33
33
  file_button: 'text-xl px-5 py-3',
34
34
  submit_button: 'text-xl px-5 py-3',
35
- multiselect_input: 'text-xl px-4 py-3'
35
+ multiselect_input: 'text-xl px-3 py-2 h-15'
36
36
  }
37
37
  }.freeze
38
38
 
@@ -0,0 +1,7 @@
1
+ - if direction == :down
2
+ %svg{ xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", "stroke-width": "1.5", stroke: "currentColor", class: SIZE_CLASSES[size] }
3
+ %path{ "stroke-linecap": "round", "stroke-linejoin": "round", d: "m19.5 8.25-7.5 7.5-7.5-7.5" }
4
+
5
+ - if direction == :up
6
+ %svg{ xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", "stroke-width": "1.5", stroke: "currentColor", class: SIZE_CLASSES[size] }
7
+ %path{ "stroke-linecap": "round", "stroke-linejoin": "round", d: "m4.5 15.75 7.5-7.5 7.5 7.5" }
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tailwinds
4
+ module Form
5
+ module Multiselect
6
+ # Caret icon component
7
+ class CaretComponent < Tramway::BaseComponent
8
+ option :direction
9
+ option :size
10
+
11
+ SIZE_CLASSES = {
12
+ small: 'w-3 h-3',
13
+ medium: 'w-4 h-4',
14
+ large: 'w-6 h-6'
15
+ }.freeze
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tailwinds
4
+ module Form
5
+ module Multiselect
6
+ # Container for dropdown component
7
+ class DropdownContainerComponent < Tramway::BaseComponent
8
+ option :size
9
+
10
+ SIZE_CLASSES = {
11
+ small: 'text-sm',
12
+ medium: 'text-base',
13
+ large: 'text-lg'
14
+ }.freeze
15
+
16
+ def dropdown_classes
17
+ theme_classes(
18
+ classic: 'absolute border-b border-l border-r border-gray-700 w-full z-40 lef-0 rounded-b-xl' \
19
+ 'max-h-select overflow-y-auto bg-gray-900 shadow-md ring-1 ring-gray-700 text-white ' \
20
+ "#{SIZE_CLASSES[size]}"
21
+ )
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,5 +1,2 @@
1
1
  %div{ class: item_classes, data: { action: "click->multiselect#toggleItem", text: "{{text}}", value: "{{value}}" } }
2
- %div{ class: item_inner_classes }
3
- %div{ class: item_text_classes }
4
- .mx-2.leading-6
5
- {{text}}
2
+ {{text}}
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tailwinds
4
+ module Form
5
+ module Multiselect
6
+ # Container for item in dropdown component
7
+ class ItemContainerComponent < Tramway::BaseComponent
8
+ option :size
9
+
10
+ SIZE_CLASSES = {
11
+ small: 'p-1',
12
+ medium: 'p-2',
13
+ large: 'p-3'
14
+ }.freeze
15
+
16
+ def item_classes
17
+ theme_classes(
18
+ classic: "cursor-pointer hover:bg-gray-800 shadow-inner option #{SIZE_CLASSES[size]}"
19
+ )
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -4,7 +4,7 @@ module Tailwinds
4
4
  module Form
5
5
  module Multiselect
6
6
  # Renders input as select
7
- class SelectAsInput < Tramway::BaseComponent
7
+ class SelectAsInputComponent < Tramway::BaseComponent
8
8
  option :options
9
9
  option :attribute
10
10
  option :input
@@ -0,0 +1,6 @@
1
+ %div{ class: selected_item_classes, data: { action: "click->multiselect#toggleItem", text: "{{text}}", value: "{{value}}" } }
2
+ .font-normal.leading-none.max-w-full.flex-initial
3
+ {{text}}
4
+ .flex.flex-auto.flex-row-reverse
5
+ .cursor-pointer
6
+
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tailwinds
4
+ module Form
5
+ module Multiselect
6
+ # Tailwind-styled multi-select field
7
+ class SelectedItemTemplateComponent < Tramway::BaseComponent
8
+ option :size
9
+
10
+ SIZE_CLASSES = {
11
+ small: 'text-sm',
12
+ medium: 'text-base',
13
+ large: 'text-lg'
14
+ }.freeze
15
+
16
+ def selected_item_classes
17
+ theme_classes(
18
+ classic: 'flex justify-center items-center font-medium py-1 px-2 rounded-xl border ' \
19
+ 'text-white border-gray-700 shadow-md hover:bg-gray-800 cursor-pointer space-x-1 ' \
20
+ 'selected-option ' + SIZE_CLASSES[size].to_s
21
+ )
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,10 +1,13 @@
1
- .mb-4
1
+ .mb-4.relative
2
2
  - if @label
3
3
  = component('tailwinds/form/label', for: @for) do
4
4
  = @label
5
- %div{ class: wrapper_classes, data: multiselect_hash, id: "#{@for}_multiselect" }
6
- .min-w-96.w-fit
7
- %div{ class: dropdown_classes, data: { "multiselect-target" => "dropdown" } }
8
- .flex.flex-auto.flex-wrap{ data: { "multiselect-target" => "showSelectedArea" } }
9
- %div{ class: dropdown_indicator_classes }
10
- ^
5
+ %div{ role: :combobox, data: multiselect_hash, id: "#{@for}_multiselect" }
6
+ - classes = "#{size_class(:multiselect_input)} #{select_base_classes}"
7
+ .flex.flex-end.justify-between{ data: dropdown_data, **dropdown_options }
8
+ .flex.flex-row.flex-nowrap.overflow-x-auto.space-x-1{ data: { "multiselect-target" => "showSelectedArea" } }
9
+ .flex.flex-col.justify-center
10
+ .caret-down{ data: { "multiselect-target" => "caretDown" } }
11
+ = component 'tailwinds/form/multiselect/caret', size: size, direction: :down
12
+ .caret-up.hidden{ data: { "multiselect-target" => "caretUp" } }
13
+ = component 'tailwinds/form/multiselect/caret', size: size, direction: :up
@@ -12,12 +12,23 @@ module Tailwinds
12
12
  end.to_json
13
13
  end
14
14
 
15
+ # rubocop:disable Metrics/MethodLength
15
16
  def multiselect_hash
16
17
  {
17
- controller:, selected_item_template:, multiselect_selected_items_value:, dropdown_container:, item_container:,
18
- items:, action:, select_as_input:, placeholder:, value:, on_change:
18
+ controller:,
19
+ selected_item_template:,
20
+ multiselect_selected_items_value:,
21
+ dropdown_container:,
22
+ item_container:,
23
+ items:,
24
+ action:,
25
+ select_as_input:,
26
+ placeholder:,
27
+ value:,
28
+ on_change:
19
29
  }.transform_keys { |key| key.to_s.gsub('_', '-') }
20
30
  end
31
+ # rubocop:enable Metrics/MethodLength
21
32
 
22
33
  def controller
23
34
  controllers = [:multiselect]
@@ -26,22 +37,20 @@ module Tailwinds
26
37
  controllers.join(' ')
27
38
  end
28
39
 
29
- def wrapper_classes
30
- theme_classes(
31
- classic: 'flex flex-col relative text-gray-200'
40
+ def dropdown_data
41
+ (options[:data] || {}).merge(
42
+ 'multiselect-target' => 'dropdown',
43
+ 'dropdown-container' => dropdown_container,
44
+ 'item-container' => item_container
32
45
  )
33
46
  end
34
47
 
35
- def dropdown_classes
36
- theme_classes(
37
- classic: 'p-1 flex border rounded-xl border-gray-700 bg-gray-900 shadow-inner'
38
- )
48
+ def dropdown_options
49
+ options.except(:data).merge(class: input_classes)
39
50
  end
40
51
 
41
- def dropdown_indicator_classes
42
- theme_classes(
43
- classic: 'w-8 py-1 pl-2 pr-1 border-l flex items-center text-gray-500 border-gray-700'
44
- )
52
+ def input_classes
53
+ "#{size_class(:multiselect_input)} #{select_base_classes}"
45
54
  end
46
55
 
47
56
  private
@@ -63,13 +72,12 @@ module Tailwinds
63
72
  end
64
73
 
65
74
  def select_as_input
66
- render(
67
- Tailwinds::Form::Multiselect::SelectAsInput.new(
68
- options:,
69
- attribute:,
70
- input:,
71
- size_class: size_class(:multiselect_input)
72
- )
75
+ component(
76
+ 'tailwinds/form/multiselect/select_as_input',
77
+ options:,
78
+ attribute:,
79
+ input:,
80
+ size_class: size_class(:multiselect_input)
73
81
  )
74
82
  end
75
83
 
@@ -87,29 +95,17 @@ module Tailwinds
87
95
  options.dig(:data, :action)
88
96
  end
89
97
 
90
- def method_missing(method_name, *, &)
91
- component = component_name(method_name)
92
-
93
- if method_name.to_s.include?('_') && Object.const_defined?(component)
94
- render(component.constantize.new(*, &))
95
- else
96
- super
97
- end
98
+ def selected_item_template
99
+ component('tailwinds/form/multiselect/selected_item_template', size:)
98
100
  end
99
101
 
100
- def respond_to_missing?(method_name, include_private = false)
101
- if method_name.to_s.include?('_') && Object.const_defined?(component_name(method_name))
102
- true
103
- else
104
- super
105
- end
102
+ def dropdown_container
103
+ component('tailwinds/form/multiselect/dropdown_container', size:)
106
104
  end
107
105
 
108
- # :reek:UtilityFunction { enabled: false }
109
- def component_name(method_name)
110
- "Tailwinds::Form::Multiselect::#{method_name.to_s.camelize}"
106
+ def item_container
107
+ component('tailwinds/form/multiselect/item_container', size:)
111
108
  end
112
- # :reek:UtilityFunction { enabled: true }
113
109
  end
114
110
  end
115
111
  end
@@ -247,7 +247,6 @@ module.exports = {
247
247
  'absolute',
248
248
  'relative',
249
249
  'shadow',
250
- 'top-11',
251
250
  'z-40',
252
251
  'max-h-select',
253
252
  'overflow-y-auto',
@@ -269,6 +268,25 @@ module.exports = {
269
268
  'outline-none',
270
269
  'h-full',
271
270
  'm-1',
271
+ 'p-1',
272
+ 'p-2',
273
+ 'p-3',
274
+ 'rounded-b-xl',
275
+ 'hover:bg-gray-800',
276
+ 'border-gray-700',
277
+ 'h-15',
278
+ 'h-12',
279
+ 'h-10',
280
+ 'w-2',
281
+ 'h-2',
282
+ 'w-4',
283
+ 'h-4',
284
+ 'w-6',
285
+ 'h-6',
286
+ 'px-2',
287
+ 'py-1',
288
+ 'flex-nowrap',
289
+ 'overflow-x-auto',
272
290
 
273
291
  // === Flash message styles ===
274
292
  'fixed',
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tramway
4
- VERSION = '2.2.4'
4
+ VERSION = '2.2.5'
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: 2.2.4
4
+ version: 2.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - kalashnikovisme
@@ -164,14 +164,16 @@ files:
164
164
  - app/components/tailwinds/form/file_field_component.rb
165
165
  - app/components/tailwinds/form/label_component.html.haml
166
166
  - app/components/tailwinds/form/label_component.rb
167
- - app/components/tailwinds/form/multiselect/dropdown_container.html.haml
168
- - app/components/tailwinds/form/multiselect/dropdown_container.rb
169
- - app/components/tailwinds/form/multiselect/item_container.html.haml
170
- - app/components/tailwinds/form/multiselect/item_container.rb
171
- - app/components/tailwinds/form/multiselect/select_as_input.html.haml
172
- - app/components/tailwinds/form/multiselect/select_as_input.rb
173
- - app/components/tailwinds/form/multiselect/selected_item_template.html.haml
174
- - app/components/tailwinds/form/multiselect/selected_item_template.rb
167
+ - app/components/tailwinds/form/multiselect/caret_component.html.haml
168
+ - app/components/tailwinds/form/multiselect/caret_component.rb
169
+ - app/components/tailwinds/form/multiselect/dropdown_container_component.html.haml
170
+ - app/components/tailwinds/form/multiselect/dropdown_container_component.rb
171
+ - app/components/tailwinds/form/multiselect/item_container_component.html.haml
172
+ - app/components/tailwinds/form/multiselect/item_container_component.rb
173
+ - app/components/tailwinds/form/multiselect/select_as_input_component.html.haml
174
+ - app/components/tailwinds/form/multiselect/select_as_input_component.rb
175
+ - app/components/tailwinds/form/multiselect/selected_item_template_component.html.haml
176
+ - app/components/tailwinds/form/multiselect/selected_item_template_component.rb
175
177
  - app/components/tailwinds/form/multiselect_component.html.haml
176
178
  - app/components/tailwinds/form/multiselect_component.rb
177
179
  - app/components/tailwinds/form/number_field_component.html.haml
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Tailwinds
4
- module Form
5
- module Multiselect
6
- # Container for dropdown component
7
- class DropdownContainer < Tramway::BaseComponent
8
- def dropdown_classes
9
- theme_classes(
10
- classic: 'absolute shadow top-11 z-40 w-full lef-0 rounded-xl max-h-select overflow-y-auto ' \
11
- 'bg-gray-900 shadow-md ring-1 ring-gray-700'
12
- )
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Tailwinds
4
- module Form
5
- module Multiselect
6
- # Container for item in dropdown component
7
- class ItemContainer < Tramway::BaseComponent
8
- def item_classes
9
- theme_classes(
10
- classic: 'cursor-pointer w-full rounded-xl border-b border-gray-700 bg-gray-900 ' \
11
- 'hover:bg-gray-800 shadow-inner'
12
- )
13
- end
14
-
15
- def item_inner_classes
16
- theme_classes(
17
- classic: 'flex w-full items-center p-2 pl-2 border-transparent border-l-2 relative ' \
18
- 'hover:border-gray-600'
19
- )
20
- end
21
-
22
- def item_text_classes
23
- theme_classes(
24
- classic: 'w-full items-center flex text-gray-100'
25
- )
26
- end
27
- end
28
- end
29
- end
30
- end
@@ -1,6 +0,0 @@
1
- %div{ class: selected_item_classes }
2
- .text-xs.font-normal.leading-none.max-w-full.flex-initial
3
- {{text}}
4
- .flex.flex-auto.flex-row-reverse
5
- .cursor-pointer{ data: { action: "click->multiselect#toggleItem", text: "{{text}}", value: "{{value}}" } }
6
-
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Tailwinds
4
- module Form
5
- module Multiselect
6
- # Tailwind-styled multi-select field
7
- class SelectedItemTemplate < Tramway::BaseComponent
8
- def selected_item_classes
9
- theme_classes(
10
- classic: 'flex justify-center items-center m-1 font-medium py-1 px-2 rounded-full border ' \
11
- 'bg-teal-900 text-teal-100 border-teal-700 shadow-md'
12
- )
13
- end
14
- end
15
- end
16
- end
17
- end