matestack-ui-bootstrap 1.4.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +17 -5
  3. data/README.md +53 -19
  4. data/lib/matestack/ui/bootstrap.rb +97 -17
  5. data/{app/concepts → lib}/matestack/ui/bootstrap/apps/admin_template.rb +14 -7
  6. data/lib/matestack/ui/bootstrap/base_component.rb +13 -0
  7. data/lib/matestack/ui/bootstrap/base_vue_js_component.rb +13 -0
  8. data/lib/matestack/ui/bootstrap/components/accordion.rb +58 -0
  9. data/{app/concepts → lib}/matestack/ui/bootstrap/components/alert.js +12 -9
  10. data/lib/matestack/ui/bootstrap/components/alert.rb +43 -0
  11. data/lib/matestack/ui/bootstrap/components/avatar.rb +27 -0
  12. data/lib/matestack/ui/bootstrap/components/badge.rb +32 -0
  13. data/lib/matestack/ui/bootstrap/components/breadcrumb.rb +50 -0
  14. data/lib/matestack/ui/bootstrap/components/button.rb +71 -0
  15. data/lib/matestack/ui/bootstrap/components/button_group.rb +36 -0
  16. data/lib/matestack/ui/bootstrap/components/card.rb +105 -0
  17. data/{app/concepts → lib}/matestack/ui/bootstrap/components/carousel.js +21 -18
  18. data/lib/matestack/ui/bootstrap/components/carousel.rb +103 -0
  19. data/{app/concepts → lib}/matestack/ui/bootstrap/components/close.rb +10 -9
  20. data/{app/concepts → lib}/matestack/ui/bootstrap/components/collapse.js +20 -17
  21. data/lib/matestack/ui/bootstrap/components/collapse.rb +54 -0
  22. data/{app/concepts → lib}/matestack/ui/bootstrap/components/dropdown.js +5 -2
  23. data/{app/concepts → lib}/matestack/ui/bootstrap/components/dropdown.rb +31 -26
  24. data/lib/matestack/ui/bootstrap/components/icon.rb +21 -0
  25. data/lib/matestack/ui/bootstrap/components/list_group.rb +148 -0
  26. data/{app/concepts → lib}/matestack/ui/bootstrap/components/modal.js +24 -21
  27. data/lib/matestack/ui/bootstrap/components/modal.rb +121 -0
  28. data/lib/matestack/ui/bootstrap/components/navbar.rb +163 -0
  29. data/{app/concepts → lib}/matestack/ui/bootstrap/components/page_heading.rb +7 -5
  30. data/{app/concepts → lib}/matestack/ui/bootstrap/components/pagination.rb +15 -13
  31. data/{app/concepts → lib}/matestack/ui/bootstrap/components/popover.js +4 -1
  32. data/{app/concepts → lib}/matestack/ui/bootstrap/components/popover.rb +26 -22
  33. data/{app/concepts → lib}/matestack/ui/bootstrap/components/progress.rb +24 -24
  34. data/lib/matestack/ui/bootstrap/components/scrollspy.rb +50 -0
  35. data/lib/matestack/ui/bootstrap/components/section_card.rb +33 -0
  36. data/lib/matestack/ui/bootstrap/components/spinner.rb +35 -0
  37. data/lib/matestack/ui/bootstrap/components/tab_nav.rb +79 -0
  38. data/lib/matestack/ui/bootstrap/components/tab_nav_content.rb +35 -0
  39. data/{app/concepts → lib}/matestack/ui/bootstrap/components/toast.js +27 -18
  40. data/lib/matestack/ui/bootstrap/components/toast.rb +113 -0
  41. data/{app/concepts → lib}/matestack/ui/bootstrap/components/tooltip.js +4 -1
  42. data/lib/matestack/ui/bootstrap/components/tooltip.rb +66 -0
  43. data/{app/concepts → lib}/matestack/ui/bootstrap/content/figure.rb +4 -2
  44. data/lib/matestack/ui/bootstrap/content/smart_collection/collection.rb +120 -0
  45. data/{app/concepts/matestack/ui/bootstrap/content/collection → lib/matestack/ui/bootstrap/content/smart_collection}/collection.scss +0 -0
  46. data/lib/matestack/ui/bootstrap/content/smart_collection/content.rb +118 -0
  47. data/{app/concepts/matestack/ui/bootstrap/content/collection → lib/matestack/ui/bootstrap/content/smart_collection}/filter.rb +7 -3
  48. data/{app/concepts/matestack/ui/bootstrap/content/collection → lib/matestack/ui/bootstrap/content/smart_collection}/paginate.rb +19 -14
  49. data/lib/matestack/ui/bootstrap/form/checkbox.rb +90 -0
  50. data/lib/matestack/ui/bootstrap/form/input.rb +118 -0
  51. data/lib/matestack/ui/bootstrap/form/radio.rb +57 -0
  52. data/lib/matestack/ui/bootstrap/form/select.rb +63 -0
  53. data/lib/matestack/ui/bootstrap/form/submit.rb +20 -0
  54. data/lib/matestack/ui/bootstrap/form/switch.rb +32 -0
  55. data/lib/matestack/ui/bootstrap/form/textarea.rb +49 -0
  56. data/lib/matestack/ui/bootstrap/index.js +24 -0
  57. data/lib/matestack/ui/bootstrap/layout/column.rb +49 -0
  58. data/{app/concepts → lib}/matestack/ui/bootstrap/layout/container.rb +12 -9
  59. data/lib/matestack/ui/bootstrap/layout/row.rb +25 -0
  60. data/{app/concepts → lib}/matestack/ui/bootstrap/layout/sidebar.js +5 -2
  61. data/{app/concepts → lib}/matestack/ui/bootstrap/layout/sidebar.rb +10 -10
  62. data/{app/concepts → lib}/matestack/ui/bootstrap/layout/sidebar.scss +0 -0
  63. data/lib/matestack/ui/bootstrap/registry.rb +173 -0
  64. data/{app/javascript/matestack-ui-bootstrap → lib/matestack/ui/bootstrap}/stylesheets/matestack-ui-bootstrap.scss +0 -0
  65. data/lib/matestack/ui/bootstrap/version.rb +1 -1
  66. data/lib/tasks/matestack/ui/bootstrap_tasks.rake +25 -25
  67. metadata +68 -76
  68. data/app/assets/images/avatar-placeholder.png +0 -0
  69. data/app/assets/images/icons/bootstrap-icons.svg +0 -1
  70. data/app/concepts/matestack/ui/bootstrap/components/accordion.rb +0 -53
  71. data/app/concepts/matestack/ui/bootstrap/components/alert.rb +0 -34
  72. data/app/concepts/matestack/ui/bootstrap/components/avatar.rb +0 -27
  73. data/app/concepts/matestack/ui/bootstrap/components/badge.rb +0 -30
  74. data/app/concepts/matestack/ui/bootstrap/components/breadcrumb.rb +0 -46
  75. data/app/concepts/matestack/ui/bootstrap/components/button.rb +0 -54
  76. data/app/concepts/matestack/ui/bootstrap/components/button_group.rb +0 -36
  77. data/app/concepts/matestack/ui/bootstrap/components/card.rb +0 -100
  78. data/app/concepts/matestack/ui/bootstrap/components/carousel.rb +0 -85
  79. data/app/concepts/matestack/ui/bootstrap/components/chart.js +0 -232
  80. data/app/concepts/matestack/ui/bootstrap/components/chart.rb +0 -71
  81. data/app/concepts/matestack/ui/bootstrap/components/collapse.rb +0 -43
  82. data/app/concepts/matestack/ui/bootstrap/components/icon.rb +0 -19
  83. data/app/concepts/matestack/ui/bootstrap/components/list_group.rb +0 -83
  84. data/app/concepts/matestack/ui/bootstrap/components/modal.rb +0 -106
  85. data/app/concepts/matestack/ui/bootstrap/components/navbar.rb +0 -120
  86. data/app/concepts/matestack/ui/bootstrap/components/scrollspy.rb +0 -33
  87. data/app/concepts/matestack/ui/bootstrap/components/section_card.rb +0 -31
  88. data/app/concepts/matestack/ui/bootstrap/components/spinner.rb +0 -31
  89. data/app/concepts/matestack/ui/bootstrap/components/tab_nav.rb +0 -81
  90. data/app/concepts/matestack/ui/bootstrap/components/tab_nav_content.rb +0 -32
  91. data/app/concepts/matestack/ui/bootstrap/components/toast.rb +0 -99
  92. data/app/concepts/matestack/ui/bootstrap/components/tooltip.rb +0 -82
  93. data/app/concepts/matestack/ui/bootstrap/content/collection/collection.rb +0 -112
  94. data/app/concepts/matestack/ui/bootstrap/content/collection/content.rb +0 -101
  95. data/app/concepts/matestack/ui/bootstrap/form/checkbox.rb +0 -90
  96. data/app/concepts/matestack/ui/bootstrap/form/date.js +0 -38
  97. data/app/concepts/matestack/ui/bootstrap/form/date.rb +0 -98
  98. data/app/concepts/matestack/ui/bootstrap/form/input.rb +0 -123
  99. data/app/concepts/matestack/ui/bootstrap/form/radio.rb +0 -65
  100. data/app/concepts/matestack/ui/bootstrap/form/select.haml +0 -11
  101. data/app/concepts/matestack/ui/bootstrap/form/select.rb +0 -74
  102. data/app/concepts/matestack/ui/bootstrap/form/submit.rb +0 -20
  103. data/app/concepts/matestack/ui/bootstrap/form/switch.rb +0 -90
  104. data/app/concepts/matestack/ui/bootstrap/layout/column.rb +0 -47
  105. data/app/concepts/matestack/ui/bootstrap/layout/row.rb +0 -15
  106. data/app/concepts/matestack/ui/bootstrap/pages/devise/sign_in.rb +0 -40
  107. data/app/concepts/matestack/ui/bootstrap/registry.rb +0 -63
  108. data/app/helpers/matestack/ui/bootstrap/application_helper.rb +0 -13
  109. data/app/javascript/matestack-ui-bootstrap/index.js +0 -26
  110. data/app/javascript/packs/matestack-ui-bootstrap.js +0 -2
  111. data/config/routes.rb +0 -2
  112. data/lib/matestack/ui/bootstrap/engine.rb +0 -26
@@ -1,29 +1,30 @@
1
- class Matestack::Ui::Bootstrap::Components::Close < Matestack::Ui::Component
1
+ require_relative "../base_component"
2
2
 
3
- optional :dismiss, class: { as: :bs_class }
3
+ class Matestack::Ui::Bootstrap::Components::Close < Matestack::Ui::Bootstrap::BaseComponent
4
+
5
+ optional :dismiss, class: { as: :bs_class }
4
6
  optional :attributes
5
7
 
6
8
  def response
7
9
  button close_attributes do
8
- span attributes: { 'aria-hidden': 'true' } do
10
+ span 'aria-hidden': 'true' do
9
11
  # plain "&times;".html_safe
10
12
  end
11
13
  end
12
14
  end
13
15
 
14
16
  def close_attributes
15
- html_attributes.merge(
17
+ options.merge(
16
18
  class: close_classes,
17
- data: { dismiss: "#{dismiss}" },
18
- type: 'button',
19
- attributes: (attributes || {}).merge({ 'aria-label': 'Close' })
20
- )
19
+ data: { "bs-dismiss": "#{context.dismiss}" },
20
+ type: 'button'
21
+ ).merge((context.attributes || {}).merge({ 'aria-label': 'Close' }))
21
22
  end
22
23
 
23
24
  def close_classes
24
25
  [].tap do |classes|
25
26
  classes << 'btn-close'
26
- classes << bs_class
27
+ classes << context.bs_class
27
28
  end.join(' ').strip
28
29
  end
29
30
 
@@ -1,6 +1,9 @@
1
1
  import * as bootstrap from 'bootstrap'
2
+ import Vue from 'vue/dist/vue.esm'
2
3
 
3
- MatestackUiCore.Vue.component('matestack-ui-bootstrap-collapse', {
4
+ import MatestackUiCore from 'matestack-ui-core'
5
+
6
+ Vue.component('matestack-ui-bootstrap-collapse', {
4
7
  mixins: [MatestackUiCore.componentMixin],
5
8
  data() {
6
9
  return {
@@ -41,43 +44,43 @@ MatestackUiCore.Vue.component('matestack-ui-bootstrap-collapse', {
41
44
  const self = this
42
45
 
43
46
  // toggle_on event registration
44
- if(self.componentConfig["toggle_on"] != undefined){
45
- var toggle_events = self.componentConfig["toggle_on"].split(",")
47
+ if(self.props["toggle_on"] != undefined){
48
+ var toggle_events = self.props["toggle_on"].split(",")
46
49
  toggle_events.forEach(toggle_event => MatestackUiCore.matestackEventHub.$on(toggle_event.trim(), self.toggle));
47
50
  }
48
51
  // show_on event registration
49
- if(self.componentConfig["show_on"] != undefined){
50
- var show_events = self.componentConfig["show_on"].split(",")
52
+ if(self.props["show_on"] != undefined){
53
+ var show_events = self.props["show_on"].split(",")
51
54
  show_events.forEach(show_event => MatestackUiCore.matestackEventHub.$on(show_event.trim(), self.show));
52
55
  }
53
56
  // hide_on event registration
54
- if(self.componentConfig["hide_on"] != undefined){
55
- var hide_events = self.componentConfig["hide_on"].split(",")
57
+ if(self.props["hide_on"] != undefined){
58
+ var hide_events = self.props["hide_on"].split(",")
56
59
  hide_events.forEach(hide_event => MatestackUiCore.matestackEventHub.$on(hide_event.trim(), self.hide));
57
60
  }
58
61
  // dispose_on event registration
59
- if(self.componentConfig["dispose_on"] != undefined){
60
- var dispose_events = self.componentConfig["dispose_on"].split(",")
62
+ if(self.props["dispose_on"] != undefined){
63
+ var dispose_events = self.props["dispose_on"].split(",")
61
64
  dispose_events.forEach(dispose_event => MatestackUiCore.matestackEventHub.$on(dispose_event.trim(), self.dispose));
62
65
  }
63
66
  },
64
67
 
65
68
  beforeDestroy: function(){
66
69
  const self = this
67
- if(self.componentConfig["toggle_on"] != undefined){
68
- var show_events = self.componentConfig["toggle_on"].split(",")
70
+ if(self.props["toggle_on"] != undefined){
71
+ var show_events = self.props["toggle_on"].split(",")
69
72
  show_events.forEach(show_event => MatestackUiCore.matestackEventHub.$off(show_event.trim(), self.show));
70
73
  }
71
- if(self.componentConfig["show_on"] != undefined){
72
- var show_events = self.componentConfig["show_on"].split(",")
74
+ if(self.props["show_on"] != undefined){
75
+ var show_events = self.props["show_on"].split(",")
73
76
  show_events.forEach(show_event => MatestackUiCore.matestackEventHub.$off(show_event.trim(), self.show));
74
77
  }
75
- if(self.componentConfig["hide_on"] != undefined){
76
- var hide_events = self.componentConfig["hide_on"].split(",")
78
+ if(self.props["hide_on"] != undefined){
79
+ var hide_events = self.props["hide_on"].split(",")
77
80
  hide_events.forEach(hide_event => MatestackUiCore.matestackEventHub.$off(hide_event.trim(), self.hide));
78
81
  }
79
- if(self.componentConfig["dispose_on"] != undefined){
80
- var dispose_events = self.componentConfig["dispose_on"].split(",")
82
+ if(self.props["dispose_on"] != undefined){
83
+ var dispose_events = self.props["dispose_on"].split(",")
81
84
  dispose_events.forEach(dispose_event => MatestackUiCore.matestackEventHub.$off(dispose_event.trim(), self.dispose));
82
85
  }
83
86
  }
@@ -0,0 +1,54 @@
1
+ require_relative "../base_vue_js_component"
2
+
3
+ class Matestack::Ui::Bootstrap::Components::Collapse < Matestack::Ui::Bootstrap::BaseVueJsComponent
4
+ vue_name "matestack-ui-bootstrap-collapse"
5
+
6
+ optional :multi, :labelledby, :parent, class: { as: :bs_class }
7
+ optional :card # possible keys: class, text
8
+ # event trigger
9
+ optional :toggle_on, :show_on, :hide_on, :dispose_on
10
+
11
+ def response
12
+ div collapse_attributes do
13
+ card_partial if context.card
14
+ yield if block_given?
15
+ end
16
+ end
17
+
18
+ protected
19
+
20
+ def vue_props
21
+ {}.tap do |props|
22
+ props[:toggle_on] = context.toggle_on
23
+ props[:show_on] = context.show_on
24
+ props[:hide_on] = context.hide_on
25
+ props[:dispose_on] = context.dispose_on
26
+ end
27
+ end
28
+
29
+ def card_partial
30
+ tmp_card = context.card.is_a?(Hash) ? context.card : { text: context.card }
31
+ div class: "card card-body #{tmp_card[:class]}".strip do
32
+ plain tmp_card[:text]
33
+ end
34
+ end
35
+
36
+ def collapse_attributes
37
+ options.merge(
38
+ class: collapse_classes,
39
+ data: { "bs-parent": context.parent },
40
+ 'aria-labelledby': "#{context.labelledby}"
41
+ )
42
+ end
43
+
44
+ def collapse_classes
45
+ [].tap do |classes|
46
+ classes << 'collapse'
47
+ # mulit target
48
+ classes << 'multi-collapse' if context.multi
49
+ #custom classes
50
+ classes << context.bs_class
51
+ end.join(' ').strip
52
+ end
53
+
54
+ end
@@ -1,6 +1,9 @@
1
1
  import * as bootstrap from 'bootstrap'
2
+ import Vue from 'vue/dist/vue.esm'
2
3
 
3
- MatestackUiCore.Vue.component('matestack-ui-bootstrap-dropdown', {
4
+ import MatestackUiCore from 'matestack-ui-core'
5
+
6
+ Vue.component('matestack-ui-bootstrap-dropdown', {
4
7
  mixins: [MatestackUiCore.componentMixin],
5
8
  data() {
6
9
  return {
@@ -8,7 +11,7 @@ MatestackUiCore.Vue.component('matestack-ui-bootstrap-dropdown', {
8
11
  };
9
12
  },
10
13
  mounted() {
11
- // var mydropdown = document.getElementById(this.componentConfig["dropdown-id"])
14
+ // var mydropdown = document.getElementById(this.props["dropdown-id"])
12
15
  // this.dropdownInstance = new bootstrap.Dropdown(mydropdown)
13
16
  }
14
17
  });
@@ -1,18 +1,22 @@
1
- class Matestack::Ui::Bootstrap::Components::Dropdown < Matestack::Ui::VueJsComponent
2
- vue_js_component_name "matestack-ui-bootstrap-dropdown"
1
+ require_relative "../base_vue_js_component"
3
2
 
4
- optional :variant, :text, :btn_class # button attributes
3
+ class Matestack::Ui::Bootstrap::Components::Dropdown < Matestack::Ui::Bootstrap::BaseVueJsComponent
4
+ vue_name "matestack-ui-bootstrap-dropdown"
5
+
6
+ optional :variant, :btn_class # button attributes
5
7
  optional :direction, :align, :offset, :reference
6
8
  # dropdown menu attributes, expects an array of items with possible keys: type, path, text
7
9
  # or hash with possible keys: items, class
8
10
  optional :menu
9
- optional class: { as: :bs_class }, id: { as: :bs_id }, data: { as: :bs_data }
10
- optional :slots
11
+ optional class: { as: :bs_class }
12
+ optional :id, :data
13
+
11
14
  optional :size
12
15
 
13
16
  def prepare
14
- @bs_menu = self.menu.is_a?(Hash) ? self.menu : { items: self.menu }
17
+ @bs_menu = context.menu.is_a?(Hash) ? context.menu : { items: context.menu }
15
18
  end
19
+
16
20
  def response
17
21
  div dropdown_attributes do
18
22
  split_btn_partial if slots && slots[:split_btn]
@@ -20,7 +24,7 @@ class Matestack::Ui::Bootstrap::Components::Dropdown < Matestack::Ui::VueJsCompo
20
24
 
21
25
  ul menu_attributes do
22
26
  menu_partial unless @bs_menu[:items].blank?
23
- yield_components
27
+ yield if block_given?
24
28
  end
25
29
  end
26
30
  end
@@ -28,9 +32,9 @@ class Matestack::Ui::Bootstrap::Components::Dropdown < Matestack::Ui::VueJsCompo
28
32
  protected
29
33
 
30
34
  def split_btn_partial
31
- slot slots[:split_btn]
35
+ slot :split_btn
32
36
  bs_btn btn_attributes do
33
- span class:"sr-only" do plain "Toggle Dropdown" end
37
+ span class:"visually-hidden" do plain "Toggle Dropdown" end
34
38
  end
35
39
  end
36
40
 
@@ -42,11 +46,13 @@ class Matestack::Ui::Bootstrap::Components::Dropdown < Matestack::Ui::VueJsCompo
42
46
  when :divider
43
47
  li do hr class: "dropdown-divider" end
44
48
  when :link
45
- li do link item.merge(class: "dropdown-item #{item[:class]}") end
49
+ li do a item.merge(class: "dropdown-item #{item[:class]}") end
46
50
  when :transition
47
51
  li do transition item.merge(class: "dropdown-item #{item[:class]}") end
48
52
  when :action
49
53
  li do action item.merge(class: "dropdown-item #{item[:class]}") do plain item[:text] end end
54
+ when :onclick
55
+ li do onclick item.merge(class: "dropdown-item #{item[:class]}", style: "cursor: pointer;" ) do plain item[:text] end end
50
56
  else
51
57
  span class: "dropdown-item-text" do plain item[:text] end
52
58
  end
@@ -54,7 +60,7 @@ class Matestack::Ui::Bootstrap::Components::Dropdown < Matestack::Ui::VueJsCompo
54
60
  end
55
61
 
56
62
  def dropdown_attributes
57
- html_attributes.merge(
63
+ options.merge(
58
64
  class: dropdown_classes
59
65
  )
60
66
  end
@@ -62,28 +68,28 @@ class Matestack::Ui::Bootstrap::Components::Dropdown < Matestack::Ui::VueJsCompo
62
68
  def dropdown_classes
63
69
  [].tap do |classes|
64
70
  classes << ((slots && slots[:split_btn]) ? 'btn-group' : 'dropdown')
65
- classes << "drop#{direction}" if direction.present?
66
- classes << bs_class
71
+ classes << "drop#{context.direction}" if context.direction.present?
72
+ classes << context.bs_class
67
73
  end.join(' ').strip
68
74
  end
69
75
 
70
76
  def btn_attributes
71
77
  {
72
- id: bs_id,
73
- text: "#{text unless (slots && slots[:split_btn])}",
74
- variant: (variant || :primary),
78
+ id: context.id,
79
+ text: "#{context.text unless (slots && slots[:split_btn])}",
80
+ variant: (context.variant || :primary),
75
81
  class: btn_classes,
76
82
  data: btn_data,
77
- size: size,
78
- attributes: { 'aria-expanded': "false" }
83
+ size: context.size,
84
+ 'aria-expanded': "false"
79
85
  }
80
86
  end
81
87
 
82
88
  def btn_data
83
- (bs_data || {}).tap do |hash|
89
+ (context.data || {}).tap do |hash|
84
90
  hash["bs-toggle"] = 'dropdown'
85
- hash[:offset] = offset if offset.present?
86
- hash[:reference] = reference if reference.present?
91
+ hash[:offset] = context.offset if context.offset.present?
92
+ hash[:reference] = context.reference if context.reference.present?
87
93
  end
88
94
  end
89
95
 
@@ -92,24 +98,23 @@ class Matestack::Ui::Bootstrap::Components::Dropdown < Matestack::Ui::VueJsCompo
92
98
  classes << 'dropdown-toggle'
93
99
  classes << 'dropdown-toggle-split' if slots && slots[:split_btn]
94
100
  #custom classes
95
- classes << btn_class
101
+ classes << context.btn_class
96
102
  end.join(' ').strip
97
103
  end
98
104
 
99
105
  def menu_attributes
100
106
  {
101
107
  class: menu_classes,
102
- data: { toggle: 'dropdown' },
103
- attributes: { 'aria-labelledby': bs_id }
108
+ 'aria-labelledby': context.id
104
109
  }
105
110
  end
106
111
 
107
112
  def menu_classes
108
113
  [].tap do |classes|
109
114
  classes << 'dropdown-menu'
110
- classes << "dropdown-menu-#{align}" if align.present?
115
+ classes << "dropdown-menu-#{context.align}" if context.align.present?
111
116
  #custom classes
112
- classes << @bs_menu[:class] if menu.is_a?(Hash)
117
+ classes << @bs_menu[:class] if context.menu.is_a?(Hash)
113
118
  end.join(' ').strip
114
119
  end
115
120
 
@@ -0,0 +1,21 @@
1
+ require_relative "../base_component"
2
+
3
+ class Matestack::Ui::Bootstrap::Components::Icon < Matestack::Ui::Bootstrap::BaseComponent
4
+
5
+ required :name
6
+ optional :size
7
+ optional class: { as: :bs_class }
8
+
9
+ def response
10
+ svg class: "bi #{context.bs_class}", width: get_size, height: get_size, fill: 'currentColor' do
11
+ unescape("<use xlink:href='#{asset_path("icons/bootstrap-icons.svg")}##{context.name}'/>")
12
+ end
13
+ end
14
+
15
+ def get_size
16
+ context.size || 20
17
+ end
18
+
19
+
20
+
21
+ end
@@ -0,0 +1,148 @@
1
+ require_relative "../base_component"
2
+
3
+ class Matestack::Ui::Bootstrap::Components::ListGroup < Matestack::Ui::Bootstrap::BaseComponent
4
+ optional :role
5
+
6
+ optional :items
7
+ optional :horizontal, :horizontal_size, :checkbox
8
+ optional :variant, class: { as: :bs_class }
9
+
10
+
11
+ def response
12
+ if actionable_items?
13
+ div list_group_attributes do
14
+ yield if block_given? unless context.items
15
+ list_partial if context.items
16
+ end
17
+ else
18
+ ul list_group_attributes do
19
+ yield if block_given? unless context.items
20
+ list_partial if context.items
21
+ end
22
+ end
23
+ end
24
+
25
+ protected
26
+
27
+ def actionable_items?
28
+ if context.items.present?
29
+ context.items.any? { |item| [:tab, :transition, :action, :link].include?(item[:type]) }
30
+ else
31
+ false
32
+ end
33
+ end
34
+
35
+ def tab_nav?
36
+ if context.items.present?
37
+ context.items.any? { |item| item[:type] == :tab }
38
+ else
39
+ false
40
+ end
41
+ end
42
+
43
+ def list_partial
44
+ context.items.each do |item|
45
+ case item[:type]
46
+ when :link
47
+ a link_attrs(item) do
48
+ text_rendering(item)
49
+ end
50
+ when :tab
51
+ a tab_attrs(item) do
52
+ text_rendering(item)
53
+ end
54
+ when :transition
55
+ transition transition_attrs(item) do
56
+ text_rendering(item)
57
+ end
58
+ when :action
59
+ action action_attrs(item) do
60
+ text_rendering(item)
61
+ end
62
+ when :label
63
+ label id: item[:id], class: "#{list_classes item, false}" do
64
+ input class: "form-check-input me-1", 'type': "checkbox", 'value': "" if context.checkbox
65
+ text_rendering(item)
66
+ end
67
+ else
68
+ li id: item[:id], class: "#{list_classes item, false}", "aria-disabled": "#{true if item[:disabled]}" do
69
+ # this implementation is useless, would need to be connected to a form through bs_form_checkbox
70
+ # input class: "form-check-input me-1", 'type': "checkbox", 'value': "", 'aria-label': "#{item[:text]}" if checkbox
71
+ text_rendering(item)
72
+ bs_badge variant: :primary, rounded: true, text: item[:badge] if item[:badge]
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ def text_rendering(item)
79
+ bs_icon name: item[:icon] if item[:icon]
80
+ plain item[:text]
81
+ end
82
+
83
+ def list_group_attributes
84
+ attributes = {}.tap do |hash|
85
+ hash[:class] = list_group_classes
86
+ hash[:role] = "tablist" if tab_nav?
87
+ end
88
+ options.merge(
89
+ attributes
90
+ )
91
+ end
92
+
93
+ def list_group_classes
94
+ [].tap do |classes|
95
+ classes << 'list-group'
96
+ classes << (context.horizontal_size.present? ? "list-group-horizontal-#{context.horizontal_size}": "list-group-horizontal") if context.horizontal
97
+ classes << 'list-group-flush' if context.variant == :flush
98
+ classes << context.bs_class
99
+ end.join(' ').strip
100
+ end
101
+
102
+ def link_attrs(item)
103
+ attrs = item
104
+ attrs[:class] = "#{list_classes item, true}"
105
+ attrs["aria-disabled"] = "#{true if item[:disabled]}" if item[:disabled]
106
+ attrs
107
+ end
108
+
109
+ def tab_attrs(item)
110
+ {}.tap do |hash|
111
+ hash[:id] = "tab-#{item[:id]}" if tab_nav?
112
+ hash[:class] = "#{list_classes item, true}"
113
+ hash[:data] = { "bs-toggle": "list" }
114
+ hash["aria-disabled"] = "#{true if item[:disabled]}" if item[:disabled]
115
+ hash['aria-controls'] = "#tab-#{item[:id]}-content"
116
+ hash[:role] = "tab"
117
+ hash[:path] = "#tab-#{item[:id]}-content"
118
+ hash[:target] = item[:target]
119
+ end
120
+ end
121
+
122
+ def transition_attrs(item)
123
+ attrs = item
124
+ attrs[:class] = "#{list_classes item, true}"
125
+ attrs["aria-disabled"] = "#{true if item[:disabled]}" if item[:disabled]
126
+ attrs
127
+ end
128
+
129
+ def action_attrs(item)
130
+ attrs = item
131
+ attrs[:class] = "#{list_classes item, true}"
132
+ attrs["aria-disabled"] = "#{true if item[:disabled]}" if item[:disabled]
133
+ attrs
134
+ end
135
+
136
+ def list_classes(item, action)
137
+ [].tap do |classes|
138
+ classes << 'list-group-item'
139
+ classes << 'list-group-item-action' if action
140
+ classes << "list-group-item-#{item[:variant]}" if item[:variant].present?
141
+ classes << 'active' if item[:active]
142
+ classes << 'disabled' if item[:disabled]
143
+ classes << 'd-flex justify-content-between align-items-center' if item[:badge].present?
144
+ classes << item[:class]
145
+ end.join(' ').strip
146
+ end
147
+
148
+ end