matestack-ui-bootstrap 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
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