matestack-ui-bootstrap 1.4.0 → 1.5.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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +65 -7
  3. data/app/concepts/matestack/ui/bootstrap/components/accordion.rb +17 -14
  4. data/app/concepts/matestack/ui/bootstrap/components/alert.rb +1 -1
  5. data/app/concepts/matestack/ui/bootstrap/components/badge.rb +4 -4
  6. data/app/concepts/matestack/ui/bootstrap/components/breadcrumb.rb +8 -6
  7. data/app/concepts/matestack/ui/bootstrap/components/button.rb +18 -3
  8. data/app/concepts/matestack/ui/bootstrap/components/carousel.rb +15 -14
  9. data/app/concepts/matestack/ui/bootstrap/components/close.rb +1 -1
  10. data/app/concepts/matestack/ui/bootstrap/components/collapse.rb +6 -6
  11. data/app/concepts/matestack/ui/bootstrap/components/dropdown.rb +3 -2
  12. data/app/concepts/matestack/ui/bootstrap/components/list_group.rb +87 -25
  13. data/app/concepts/matestack/ui/bootstrap/components/modal.rb +1 -1
  14. data/app/concepts/matestack/ui/bootstrap/components/navbar.rb +54 -20
  15. data/app/concepts/matestack/ui/bootstrap/components/pagination.rb +5 -5
  16. data/app/concepts/matestack/ui/bootstrap/components/popover.rb +1 -1
  17. data/app/concepts/matestack/ui/bootstrap/components/progress.rb +7 -7
  18. data/app/concepts/matestack/ui/bootstrap/components/scrollspy.rb +15 -0
  19. data/app/concepts/matestack/ui/bootstrap/components/spinner.rb +1 -1
  20. data/app/concepts/matestack/ui/bootstrap/components/tab_nav.rb +4 -2
  21. data/app/concepts/matestack/ui/bootstrap/components/toast.js +7 -1
  22. data/app/concepts/matestack/ui/bootstrap/components/tooltip.rb +8 -26
  23. data/app/concepts/matestack/ui/bootstrap/content/{collection → smart_collection}/collection.rb +18 -16
  24. data/app/concepts/matestack/ui/bootstrap/content/{collection → smart_collection}/collection.scss +0 -0
  25. data/app/concepts/matestack/ui/bootstrap/content/{collection → smart_collection}/content.rb +3 -3
  26. data/app/concepts/matestack/ui/bootstrap/content/{collection → smart_collection}/filter.rb +3 -3
  27. data/app/concepts/matestack/ui/bootstrap/content/{collection → smart_collection}/paginate.rb +3 -3
  28. data/app/concepts/matestack/ui/bootstrap/form/checkbox.rb +55 -46
  29. data/app/concepts/matestack/ui/bootstrap/form/input.rb +5 -16
  30. data/app/concepts/matestack/ui/bootstrap/form/radio.rb +22 -30
  31. data/app/concepts/matestack/ui/bootstrap/form/select.rb +12 -33
  32. data/app/concepts/matestack/ui/bootstrap/form/submit.rb +3 -2
  33. data/app/concepts/matestack/ui/bootstrap/form/switch.rb +80 -71
  34. data/app/concepts/matestack/ui/bootstrap/registry.rb +2 -4
  35. data/app/helpers/matestack/ui/bootstrap/application_helper.rb +9 -5
  36. data/app/javascript/matestack-ui-bootstrap/index.js +1 -3
  37. data/app/matestack/bootstrap/form/submit.rb +20 -0
  38. data/lib/matestack/ui/bootstrap/engine.rb +2 -2
  39. data/lib/matestack/ui/bootstrap/version.rb +1 -1
  40. data/lib/tasks/matestack/ui/bootstrap_tasks.rake +25 -25
  41. metadata +8 -12
  42. data/app/concepts/matestack/ui/bootstrap/components/chart.js +0 -232
  43. data/app/concepts/matestack/ui/bootstrap/components/chart.rb +0 -71
  44. data/app/concepts/matestack/ui/bootstrap/form/date.js +0 -38
  45. data/app/concepts/matestack/ui/bootstrap/form/date.rb +0 -98
  46. data/app/concepts/matestack/ui/bootstrap/form/select.haml +0 -11
@@ -63,7 +63,7 @@ class Matestack::Ui::Bootstrap::Components::Modal < Matestack::Ui::VueJsComponen
63
63
  slot slots[:footer] if slots && slots[:footer]
64
64
  if footer[:text].present?
65
65
  button class: "btn #{footer[:class].present? ? footer[:class] : 'btn-secondary'}",
66
- data: { dismiss: 'modal' }, attributes: { type: 'button' },
66
+ data: { "bs-dismiss": 'modal' }, attributes: { type: 'button' },
67
67
  text: footer[:text]
68
68
  end
69
69
  end
@@ -4,7 +4,7 @@ class Matestack::Ui::Bootstrap::Components::Navbar < Matestack::Ui::Component
4
4
  optional *POS_ATTRIBUTES
5
5
 
6
6
  optional class: { as: :bs_class }
7
- optional :items, :items_class, :theme, :hide_at, :color, :container_size
7
+ optional :items, :items_class, :theme, :expand_at, :color, :container_size
8
8
  optional :collapse_class
9
9
  # brand expect hash or string, possible keys for hash: text, path, img
10
10
  optional :brand
@@ -37,26 +37,43 @@ class Matestack::Ui::Bootstrap::Components::Navbar < Matestack::Ui::Component
37
37
  def brand_partial
38
38
  brand = self.brand.is_a?(Hash) ? self.brand : { text: self.brand }
39
39
  path = brand[:path].present? ? brand[:path] : "/"
40
- link class: "navbar-brand", path: path do
41
- img height: 40, path: brand[:img], attributes: { loading: "lazy" } if brand[:img].present?
42
- plain brand[:text]
40
+ brand[:path] = path
41
+ case brand[:type]
42
+ when :link
43
+ link brand.except(:text).merge(class: "navbar-brand") do
44
+ img height: 40, path: brand[:img], attributes: { loading: "lazy" } if brand[:img].present?
45
+ plain brand[:text]
46
+ end
47
+ else
48
+ transition brand.except(:text).merge(class: "navbar-brand") do
49
+ img height: 40, path: brand[:img], attributes: { loading: "lazy" } if brand[:img].present?
50
+ plain brand[:text]
51
+ end
43
52
  end
44
53
  end
45
54
 
46
55
  def navbar_content_partial
47
56
  div class: "collapse navbar-collapse #{collapse_class}", id: 'matestackNavbarContent' do
48
- ul class: items_classes do
49
- items.each do |item|
50
- li class: "nav-item" do
51
- if item[:type] == :link
52
- link class: "nav-link", path: item[:path] do
53
- bs_icon name: item[:icon], size: 20 if item[:icon]
54
- span class: "ps-3", text: item[:text] if item[:text]
55
- end
56
- else
57
- transition class: "nav-link", path: item[:path], delay: item[:delay] do
58
- bs_icon name: item[:icon], size: 20 if item[:icon]
59
- span class: "ps-3", text: item[:text] if item[:text]
57
+ if items.present?
58
+ ul class: items_classes do
59
+ items.each do |item|
60
+ li class: "nav-item" do
61
+ case item[:type]
62
+ when :link
63
+ link link_config(item) do
64
+ bs_icon name: item[:icon], size: 20 if item[:icon]
65
+ span class: "ps-3", text: item[:text] if item[:text]
66
+ end
67
+ when :action
68
+ action action_config(item) do
69
+ bs_icon name: item[:icon], size: 20 if item[:icon]
70
+ span class: "ps-3", text: item[:text] if item[:text]
71
+ end
72
+ else
73
+ transition transition_config(item) do
74
+ bs_icon name: item[:icon], size: 20 if item[:icon]
75
+ span class: "ps-3", text: item[:text] if item[:text]
76
+ end
60
77
  end
61
78
  end
62
79
  end
@@ -66,6 +83,24 @@ class Matestack::Ui::Bootstrap::Components::Navbar < Matestack::Ui::Component
66
83
  end
67
84
  end
68
85
 
86
+ def link_config(item)
87
+ config = item.except(:text)
88
+ config[:class] = "nav-link"
89
+ config
90
+ end
91
+
92
+ def transition_config(item)
93
+ config = item.except(:text)
94
+ config[:class] = "nav-link"
95
+ config
96
+ end
97
+
98
+ def action_config(item)
99
+ config = item.except(:text)
100
+ config[:class] = "nav-link"
101
+ config
102
+ end
103
+
69
104
  def navbar_attributes
70
105
  html_attributes.merge(
71
106
  class: navbar_classes
@@ -78,7 +113,7 @@ class Matestack::Ui::Bootstrap::Components::Navbar < Matestack::Ui::Component
78
113
  POS_ATTRIBUTES.each do |pos|
79
114
  classes << "#{pos}".gsub('_','-') if self.send("#{pos}")
80
115
  end
81
- classes << "navbar-expand-#{ (hide_at.present? ? hide_at : "lg") }"
116
+ classes << "navbar-expand-#{ (expand_at.present? ? expand_at : "lg") }"
82
117
  classes << "navbar-#{theme}" if theme.present?
83
118
  classes << (color.present? ? "bg-#{color}" : "bg-#{theme}") if theme || color
84
119
  classes << bs_class
@@ -96,8 +131,7 @@ class Matestack::Ui::Bootstrap::Components::Navbar < Matestack::Ui::Component
96
131
 
97
132
  def toggle_attributes
98
133
  toggle_classes = [].tap do |classes|
99
- classes << 'd-lg-none'
100
- classes << 'btn btn-link'
134
+ classes << 'btn btn-link navbar-toggler'
101
135
  classes << "ms-auto" if @toggle[:position] == :right
102
136
  classes << "me-auto" if @toggle[:position] == :left
103
137
  classes << @toggle[:class] if @toggle[:class]
@@ -105,7 +139,7 @@ class Matestack::Ui::Bootstrap::Components::Navbar < Matestack::Ui::Component
105
139
 
106
140
  {}.tap do |hash|
107
141
  hash[:class] = toggle_classes
108
- hash[:data] = { toggle: 'collapse', target: '#matestackNavbarContent' }
142
+ hash[:data] = { "bs-toggle": 'collapse', "bs-target": '#matestackNavbarContent' }
109
143
  hash[:attributes] = { 'aria-controls': 'matestackNavbarContent', 'aria-expanded': 'false', 'aria-label': 'Toggle navigation' }
110
144
  end
111
145
  end
@@ -1,18 +1,18 @@
1
1
  class Matestack::Ui::Bootstrap::Components::Pagination < Matestack::Ui::Component
2
-
2
+
3
3
  optional :aria_label, :size, class: { as: :bs_class }
4
4
  optional :items
5
5
 
6
- def response
6
+ def response
7
7
  nav pagination_attributes do
8
8
  ul class: ul_classes do
9
9
  if items.present?
10
10
  items.each do |item|
11
11
  li class: "page-item #{ 'active' if item[:active] }" do
12
12
  if item[:type] == :link
13
- link path: item[:path], text: item[:text], class: 'page-link'
13
+ link item.merge({ class: 'page-link' })
14
14
  else
15
- transition path: item[:path], text: item[:text], class: 'page-link'
15
+ transition item.merge({ class: 'page-link' })
16
16
  end
17
17
  end
18
18
  end
@@ -37,4 +37,4 @@ class Matestack::Ui::Bootstrap::Components::Pagination < Matestack::Ui::Componen
37
37
  end.join(' ').strip
38
38
  end
39
39
 
40
- end
40
+ end
@@ -49,7 +49,7 @@ class Matestack::Ui::Bootstrap::Components::Popover < Matestack::Ui::VueJsCompon
49
49
  content_partial
50
50
  end
51
51
  else
52
- btn popover_attributes do
52
+ bs_btn popover_attributes do
53
53
  content_partial
54
54
  end
55
55
  end
@@ -1,18 +1,18 @@
1
1
  class Matestack::Ui::Bootstrap::Components::Progress < Matestack::Ui::Component
2
-
2
+
3
3
  optional class: { as: :bs_class }
4
4
  optional :text, :valuemin, :valuemax
5
5
  # progress expects a number or a list containing hashes with at least a :value
6
6
  # other options are :text, :class, :variant, :striped, :animated, :aria_valuenow
7
7
  optional :progress
8
- # :value
8
+ optional :value
9
9
  optional :variant, :striped, :animated, :height
10
10
 
11
- def response
11
+ def response
12
12
  div progress_attributes do
13
13
  progress = self.progress.is_a?(Array) ? self.progress : [{ value: self.progress || value, text: self.text }]
14
14
  progress.each do |prog|
15
- progress_bar(prog[:value], valuemin, valuemax,
15
+ progress_bar(prog[:value], valuemin, valuemax,
16
16
  text: prog[:text], klass: prog[:class], variant: prog[:variant] || variant,
17
17
  striped: prog[:striped] || striped, animated: prog[:animated] || animated,
18
18
  aria_valuenow: prog[:aria_valuenow]
@@ -27,7 +27,7 @@ class Matestack::Ui::Bootstrap::Components::Progress < Matestack::Ui::Component
27
27
  def progress_attributes
28
28
  attributes = {}.tap do |hash|
29
29
  hash[:class] = "progress #{bs_class}".strip
30
- hash[:attributes] = { style: "height: #{height}px;" } if height
30
+ hash[:attributes] = { style: "height: #{height}px;" } if height
31
31
  end
32
32
  html_attributes.merge(
33
33
  attributes
@@ -36,7 +36,7 @@ class Matestack::Ui::Bootstrap::Components::Progress < Matestack::Ui::Component
36
36
 
37
37
  def progress_bar(value, min, max, text: nil, klass: nil, variant: :primary, striped: false, animated: false, aria_valuenow: nil)
38
38
  div progress_bar_attributes(value, klass, variant, striped, animated, aria_valuenow) do
39
- plain text if text
39
+ plain text if text
40
40
  end
41
41
  end
42
42
 
@@ -62,4 +62,4 @@ class Matestack::Ui::Bootstrap::Components::Progress < Matestack::Ui::Component
62
62
  classes << klass
63
63
  end.join(' ').strip
64
64
  end
65
- end
65
+ end
@@ -1,5 +1,7 @@
1
1
  class Matestack::Ui::Bootstrap::Components::Scrollspy < Matestack::Ui::Component
2
2
 
3
+ requires :height
4
+
3
5
  optional :offset # pixel to offset from top, by default 10
4
6
  optional method: { as: :bs_method} # find which section, by default auto
5
7
  optional :target # scroll target id
@@ -19,12 +21,25 @@ class Matestack::Ui::Bootstrap::Components::Scrollspy < Matestack::Ui::Component
19
21
  hash[:data] = { "bs-spy": "scroll", "bs-target": "#{target}" }
20
22
  hash[:data].merge!("bs-offset": offset) if offset.present?
21
23
  hash[:data].merge!("bs-method": :"#{bs_method}") if bs_method.present?
24
+ hash[:style] = "overflow-y: scroll; position: relative;"
25
+ hash[:style] << "height: #{parsed_height};"
26
+ hash[:tabindex] = 0
22
27
  end
23
28
  html_attributes.merge(
24
29
  attributes
25
30
  )
26
31
  end
27
32
 
33
+ def parsed_height
34
+ if height.present?
35
+ if height.to_s.include?("px") || height.to_s.include?("em") || height.to_s.include?("rem")
36
+ height
37
+ else
38
+ "#{height}px"
39
+ end
40
+ end
41
+ end
42
+
28
43
  def scrollspy_classes
29
44
  [].tap do |classes|
30
45
  classes << bs_class
@@ -5,7 +5,7 @@ class Matestack::Ui::Bootstrap::Components::Spinner < Matestack::Ui::Component
5
5
 
6
6
  def response
7
7
  div spinner_attributes do
8
- span class: "sr-only", text: sr_only
8
+ span class: "visually-hidden", text: sr_only
9
9
  end
10
10
  end
11
11
 
@@ -7,8 +7,10 @@ class Matestack::Ui::Bootstrap::Components::TabNav < Matestack::Ui::Component
7
7
  class: { as: :bs_class }, attributes: { as: :bs_attrs}
8
8
 
9
9
  def response
10
- ul nav_attributes do
11
- nav_items_partial if items.present?
10
+ if items.present?
11
+ ul nav_attributes do
12
+ nav_items_partial
13
+ end
12
14
  end
13
15
  div class: "tab-content", id: "#{id}Content" do
14
16
  yield_components
@@ -18,7 +18,13 @@ MatestackUiCore.Vue.component('matestack-ui-bootstrap-toast', {
18
18
  self.showing = false;
19
19
  }, 5000);
20
20
  }
21
- this.showing = true
21
+ if(this.componentConfig["delay"]){
22
+ setTimeout(function () {
23
+ self.showing = true;
24
+ }, parseInt(self.componentConfig["delay"]));
25
+ } else {
26
+ self.showing = true
27
+ }
22
28
  this.eventData = event
23
29
  },
24
30
  hide: function(event){
@@ -11,48 +11,32 @@ class Matestack::Ui::Bootstrap::Components::Tooltip < Matestack::Ui::VueJsCompon
11
11
  # for security reasons the sanitize, sanitizeFn and whiteList options cannot be supplied using data attributes.
12
12
  # sanitize sanitize_fn white_list
13
13
  # optional :content
14
+ requires :tooltip_title
14
15
  optional :tag
15
16
  optional class: { as: :bs_class }
16
17
  optional id: { as: :bs_id }
17
- DATA_ATTRIBUTES = %i[title text variant animation placement tabindex trigger boundary offset popper_config]
18
+ DATA_ATTRIBUTES = %i[text variant animation placement tabindex trigger boundary offset popper_config]
18
19
  optional *DATA_ATTRIBUTES
19
20
 
20
21
  def response
21
22
  case tag
22
23
  when :div
23
24
  div tooltip_attributes do
24
- element_partial
25
+ yield_components
25
26
  end
26
- when :span
27
- span tooltip_attributes do
28
- element_partial
29
- end
30
- when :link
31
- link tooltip_attributes
32
27
  else
33
- bs_btn tooltip_attributes
28
+ span tooltip_attributes do
29
+ yield_components
30
+ end
34
31
  end
35
32
  end
36
33
 
37
34
  protected
38
35
 
39
- def element_partial
40
- if options[:slots] && options[:slots][:element]
41
- slot options[:slots][:element]
42
- else
43
- bs_btn variant: variant, attributes: { 'style': "pointer-events: none;" }, text: text
44
- end
45
- end
46
-
47
36
  def tooltip_attributes
48
37
  attributes = {}.tap do |hash|
49
38
  hash[:class] = tooltip_classes
50
- hash[:style] = variant if (tag == :button or !tag.present?)
51
-
52
- hash[:attributes] = { role: "button", title: "#{title}", tabindex: "#{tabindex}" } if (tag == :link or tag == :a)
53
-
54
39
  hash[:text] = text if text.present?
55
-
56
40
  hash[:data] = {}.tap do |hash|
57
41
  DATA_ALIAS_ATTRIBUTES.each do |attribute|
58
42
  hash["bs-#{attribute}"] = self.send(:"bs_#{attribute}") if self.send(:"bs_#{attribute}")
@@ -62,7 +46,8 @@ class Matestack::Ui::Bootstrap::Components::Tooltip < Matestack::Ui::VueJsCompon
62
46
  end
63
47
  hash["bs-toggle"] = "tooltip"
64
48
  hash["bs-type"] = tag
65
- # hash[:'original-title'] = content
49
+ hash["bs-placement"] = "auto" if placement.nil?
50
+ hash["bs-title"] = tooltip_title
66
51
  end
67
52
  end
68
53
  html_attributes.merge(
@@ -72,9 +57,6 @@ class Matestack::Ui::Bootstrap::Components::Tooltip < Matestack::Ui::VueJsCompon
72
57
 
73
58
  def tooltip_classes
74
59
  [].tap do |classes|
75
- classes << "d-inline-block" if (tag == :span or tag == :div)
76
- classes << "btn btn-#{variant || 'link'}" if (tag == :link or !tag.present?)
77
-
78
60
  classes << bs_class
79
61
  end.join(' ').strip
80
62
  end
@@ -1,8 +1,8 @@
1
- class Matestack::Ui::Bootstrap::Content::Collection::Collection < Matestack::Ui::Component
1
+ class Matestack::Ui::Bootstrap::Content::SmartCollection::Collection < Matestack::Ui::Component
2
2
  include Matestack::Ui::Core::Collection::Helper
3
- include Matestack::Ui::Bootstrap::Content::Collection::Content
4
- include Matestack::Ui::Bootstrap::Content::Collection::Filter
5
- include Matestack::Ui::Bootstrap::Content::Collection::Paginate
3
+ include Matestack::Ui::Bootstrap::Content::SmartCollection::Content
4
+ include Matestack::Ui::Bootstrap::Content::SmartCollection::Filter
5
+ include Matestack::Ui::Bootstrap::Content::SmartCollection::Paginate
6
6
 
7
7
  # html attributes
8
8
  optional id: { as: :bs_id }
@@ -29,7 +29,7 @@ class Matestack::Ui::Bootstrap::Content::Collection::Collection < Matestack::Ui:
29
29
  attr_accessor :processed_filters
30
30
 
31
31
  def response
32
- div class: "smart-collection" do
32
+ div id: bs_id, class: "smart-collection" do
33
33
  filter_partial
34
34
  content
35
35
  end
@@ -57,18 +57,20 @@ class Matestack::Ui::Bootstrap::Content::Collection::Collection < Matestack::Ui:
57
57
  def filtered_query
58
58
  return @filtered_query if @filtered_query
59
59
  @filtered_query = items
60
- filters.select { |key, value| '.'.in? key.to_s }.each do |key, value|
61
- associated_name = key.to_s.split(".").first
62
- @filtered_query = @filtered_query.joins(associated_name.to_sym).all
63
- if value.is_a?(Hash)
64
- processed_filters[key] = value
65
- @filtered_query = add_query_filter(@filtered_query, associated_name, key, value)
60
+ unless filters.nil?
61
+ filters.select { |key, value| '.'.in? key.to_s }.each do |key, value|
62
+ associated_name = key.to_s.split(".").first
63
+ @filtered_query = @filtered_query.joins(associated_name.to_sym).all
64
+ if value.is_a?(Hash)
65
+ processed_filters[key] = value
66
+ @filtered_query = add_query_filter(@filtered_query, associated_name, key, value)
67
+ end
66
68
  end
67
- end
68
- filters.reject { |key, value| '.'.in? key.to_s }.each do |key, value|
69
- if value.is_a?(Hash)
70
- processed_filters[key] = value
71
- @filtered_query = add_query_filter(@filtered_query, nil, key, value)
69
+ filters.reject { |key, value| '.'.in? key.to_s }.each do |key, value|
70
+ if value.is_a?(Hash)
71
+ processed_filters[key] = value
72
+ @filtered_query = add_query_filter(@filtered_query, nil, key, value)
73
+ end
72
74
  end
73
75
  end
74
76
  @filtered_query
@@ -1,9 +1,9 @@
1
- module Matestack::Ui::Bootstrap::Content::Collection::Content
1
+ module Matestack::Ui::Bootstrap::Content::SmartCollection::Content
2
2
 
3
3
  def content
4
- bs_row id: 'content' do
4
+ bs_row class: 'smart-collection-content' do
5
5
  bs_col do
6
- async id: collection_id, rerender_on: "#{collection_id}-update, #{rerender_on} " do
6
+ async id: "#{collection_id}-async", rerender_on: "#{collection_id}-update, #{rerender_on} " do
7
7
  collection_content collection.config do
8
8
  div class: responsive_class do
9
9
  if slots && slots[:collection_rendering]
@@ -1,4 +1,4 @@
1
- module Matestack::Ui::Bootstrap::Content::Collection::Filter
1
+ module Matestack::Ui::Bootstrap::Content::SmartCollection::Filter
2
2
 
3
3
  def filter_partial
4
4
  collection_filter collection.config do
@@ -24,9 +24,9 @@ module Matestack::Ui::Bootstrap::Content::Collection::Filter
24
24
  }
25
25
  case config[:type]
26
26
  when :select
27
- collection_filter_select attributes.merge(class: 'form-select', options: config[:options])
27
+ collection_filter_select attributes.merge(id: key, class: 'form-select', options: config[:options])
28
28
  else
29
- collection_filter_input attributes.merge(class: 'form-control')
29
+ collection_filter_input attributes.merge(id: key, class: 'form-control smart-collection-filter')
30
30
  end
31
31
  end
32
32