matestack-ui-bootstrap 1.4.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 (82) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +8 -0
  3. data/README.md +26 -0
  4. data/Rakefile +43 -0
  5. data/app/assets/images/avatar-placeholder.png +0 -0
  6. data/app/assets/images/icons/bootstrap-icons.svg +1 -0
  7. data/app/concepts/matestack/ui/bootstrap/apps/admin_template.rb +85 -0
  8. data/app/concepts/matestack/ui/bootstrap/components/accordion.rb +53 -0
  9. data/app/concepts/matestack/ui/bootstrap/components/alert.js +53 -0
  10. data/app/concepts/matestack/ui/bootstrap/components/alert.rb +34 -0
  11. data/app/concepts/matestack/ui/bootstrap/components/avatar.rb +27 -0
  12. data/app/concepts/matestack/ui/bootstrap/components/badge.rb +30 -0
  13. data/app/concepts/matestack/ui/bootstrap/components/breadcrumb.rb +46 -0
  14. data/app/concepts/matestack/ui/bootstrap/components/button.rb +54 -0
  15. data/app/concepts/matestack/ui/bootstrap/components/button_group.rb +36 -0
  16. data/app/concepts/matestack/ui/bootstrap/components/card.rb +100 -0
  17. data/app/concepts/matestack/ui/bootstrap/components/carousel.js +79 -0
  18. data/app/concepts/matestack/ui/bootstrap/components/carousel.rb +85 -0
  19. data/app/concepts/matestack/ui/bootstrap/components/chart.js +232 -0
  20. data/app/concepts/matestack/ui/bootstrap/components/chart.rb +71 -0
  21. data/app/concepts/matestack/ui/bootstrap/components/close.rb +30 -0
  22. data/app/concepts/matestack/ui/bootstrap/components/collapse.js +84 -0
  23. data/app/concepts/matestack/ui/bootstrap/components/collapse.rb +43 -0
  24. data/app/concepts/matestack/ui/bootstrap/components/dropdown.js +14 -0
  25. data/app/concepts/matestack/ui/bootstrap/components/dropdown.rb +116 -0
  26. data/app/concepts/matestack/ui/bootstrap/components/icon.rb +19 -0
  27. data/app/concepts/matestack/ui/bootstrap/components/list_group.rb +83 -0
  28. data/app/concepts/matestack/ui/bootstrap/components/modal.js +90 -0
  29. data/app/concepts/matestack/ui/bootstrap/components/modal.rb +106 -0
  30. data/app/concepts/matestack/ui/bootstrap/components/navbar.rb +120 -0
  31. data/app/concepts/matestack/ui/bootstrap/components/page_heading.rb +28 -0
  32. data/app/concepts/matestack/ui/bootstrap/components/pagination.rb +40 -0
  33. data/app/concepts/matestack/ui/bootstrap/components/popover.js +26 -0
  34. data/app/concepts/matestack/ui/bootstrap/components/popover.rb +92 -0
  35. data/app/concepts/matestack/ui/bootstrap/components/progress.rb +65 -0
  36. data/app/concepts/matestack/ui/bootstrap/components/scrollspy.rb +33 -0
  37. data/app/concepts/matestack/ui/bootstrap/components/section_card.rb +31 -0
  38. data/app/concepts/matestack/ui/bootstrap/components/spinner.rb +31 -0
  39. data/app/concepts/matestack/ui/bootstrap/components/tab_nav.rb +81 -0
  40. data/app/concepts/matestack/ui/bootstrap/components/tab_nav_content.rb +32 -0
  41. data/app/concepts/matestack/ui/bootstrap/components/toast.js +79 -0
  42. data/app/concepts/matestack/ui/bootstrap/components/toast.rb +99 -0
  43. data/app/concepts/matestack/ui/bootstrap/components/tooltip.js +26 -0
  44. data/app/concepts/matestack/ui/bootstrap/components/tooltip.rb +82 -0
  45. data/app/concepts/matestack/ui/bootstrap/content/collection/collection.rb +112 -0
  46. data/app/concepts/matestack/ui/bootstrap/content/collection/collection.scss +10 -0
  47. data/app/concepts/matestack/ui/bootstrap/content/collection/content.rb +101 -0
  48. data/app/concepts/matestack/ui/bootstrap/content/collection/filter.rb +33 -0
  49. data/app/concepts/matestack/ui/bootstrap/content/collection/paginate.rb +92 -0
  50. data/app/concepts/matestack/ui/bootstrap/content/figure.rb +7 -0
  51. data/app/concepts/matestack/ui/bootstrap/form/checkbox.rb +90 -0
  52. data/app/concepts/matestack/ui/bootstrap/form/date.js +38 -0
  53. data/app/concepts/matestack/ui/bootstrap/form/date.rb +98 -0
  54. data/app/concepts/matestack/ui/bootstrap/form/input.rb +123 -0
  55. data/app/concepts/matestack/ui/bootstrap/form/radio.rb +65 -0
  56. data/app/concepts/matestack/ui/bootstrap/form/select.haml +11 -0
  57. data/app/concepts/matestack/ui/bootstrap/form/select.rb +74 -0
  58. data/app/concepts/matestack/ui/bootstrap/form/submit.rb +20 -0
  59. data/app/concepts/matestack/ui/bootstrap/form/switch.rb +90 -0
  60. data/app/concepts/matestack/ui/bootstrap/layout/column.rb +47 -0
  61. data/app/concepts/matestack/ui/bootstrap/layout/container.rb +25 -0
  62. data/app/concepts/matestack/ui/bootstrap/layout/row.rb +15 -0
  63. data/app/concepts/matestack/ui/bootstrap/layout/sidebar.js +64 -0
  64. data/app/concepts/matestack/ui/bootstrap/layout/sidebar.rb +45 -0
  65. data/app/concepts/matestack/ui/bootstrap/layout/sidebar.scss +57 -0
  66. data/app/concepts/matestack/ui/bootstrap/pages/devise/sign_in.rb +40 -0
  67. data/app/concepts/matestack/ui/bootstrap/registry.rb +63 -0
  68. data/app/helpers/matestack/ui/bootstrap/application_helper.rb +13 -0
  69. data/app/javascript/matestack-ui-bootstrap/index.js +26 -0
  70. data/app/javascript/matestack-ui-bootstrap/stylesheets/matestack-ui-bootstrap.scss +65 -0
  71. data/app/javascript/packs/matestack-ui-bootstrap.js +2 -0
  72. data/config/routes.rb +2 -0
  73. data/config/webpack/development.js +5 -0
  74. data/config/webpack/environment.js +29 -0
  75. data/config/webpack/production.js +33 -0
  76. data/config/webpack/test.js +5 -0
  77. data/config/webpacker.yml +96 -0
  78. data/lib/matestack/ui/bootstrap.rb +27 -0
  79. data/lib/matestack/ui/bootstrap/engine.rb +26 -0
  80. data/lib/matestack/ui/bootstrap/version.rb +7 -0
  81. data/lib/tasks/matestack/ui/bootstrap_tasks.rake +66 -0
  82. metadata +137 -0
@@ -0,0 +1,71 @@
1
+ class Matestack::Ui::Bootstrap::Components::Chart < Matestack::Ui::VueJsComponent
2
+ vue_js_component_name "matestack-ui-bootstrap-chart"
3
+
4
+ requires :type
5
+ requires :datasets
6
+ optional :labels
7
+ optional :height
8
+ optional :width
9
+ optional :display_legend
10
+ optional :display_x_axes
11
+ optional :display_y_axes
12
+ optional :cutout_percentage
13
+ optional class: { as: :bs_class }
14
+
15
+ def setup
16
+ @component_config[:type] = type
17
+ @component_config[:datasets] = datasets
18
+ @component_config[:labels] = labels
19
+ @component_config[:display_legend] = !display_legend.nil? ? display_legend : false
20
+ @component_config[:display_x_axes] = !display_x_axes.nil? ? display_x_axes : true
21
+ @component_config[:display_y_axes] = !display_y_axes.nil? ? display_y_axes : true
22
+ @component_config[:display_y_axes] = !display_y_axes.nil? ? display_y_axes : true
23
+ @component_config[:cutout_percentage] = !cutout_percentage.nil? ? cutout_percentage : 70
24
+ end
25
+
26
+ def response
27
+ div class: "chart-container #{bs_class}", attributes: { style: "width: 100%; height: 100%;" } do
28
+ plain "<canvas ref='chart'></canvas>".html_safe
29
+ end
30
+ end
31
+
32
+ end
33
+
34
+ # chart class: "w-50", type: :bar, datasets: [
35
+ # {
36
+ # label: "€",
37
+ # data: [total, last_7_days, last_30_days],
38
+ # backgroundColor: :primary
39
+ # },
40
+ # ], labels: ["total", "last 7 days", "last 30 days"]
41
+
42
+ # chart type: :doughnut, datasets: [
43
+ # {
44
+ # label: "€",
45
+ # data: [total, last_7_days, last_30_days],
46
+ # backgroundColor: [:orange, :secondary, :primary]
47
+ # },
48
+ # ], labels: ["total", "last 7 days", "last 30 days"]
49
+
50
+ # chart type: :line, datasets: [
51
+ # {
52
+ # label: "€",
53
+ # data: [total, last_7_days, last_30_days],
54
+ # borderColor: :primary,
55
+ # pointRadius: 0
56
+ # },
57
+ # {
58
+ # label: "€",
59
+ # data: [last_7_days, total, last_30_days],
60
+ # borderColor: :danger,
61
+ # fill: false
62
+ # },
63
+ # ], labels: ["total", "last 7 days", "last 30 days"], display_x_axes: false, display_y_axes: false
64
+
65
+ # chart type: :pie, datasets: [
66
+ # {
67
+ # label: "€",
68
+ # data: [total, last_7_days, last_30_days],
69
+ # backgroundColor: [:orange, :secondary, :primary]
70
+ # },
71
+ # ], labels: ["total", "last 7 days", "last 30 days"]
@@ -0,0 +1,30 @@
1
+ class Matestack::Ui::Bootstrap::Components::Close < Matestack::Ui::Component
2
+
3
+ optional :dismiss, class: { as: :bs_class }
4
+ optional :attributes
5
+
6
+ def response
7
+ button close_attributes do
8
+ span attributes: { 'aria-hidden': 'true' } do
9
+ # plain "&times;".html_safe
10
+ end
11
+ end
12
+ end
13
+
14
+ def close_attributes
15
+ html_attributes.merge(
16
+ class: close_classes,
17
+ data: { dismiss: "#{dismiss}" },
18
+ type: 'button',
19
+ attributes: (attributes || {}).merge({ 'aria-label': 'Close' })
20
+ )
21
+ end
22
+
23
+ def close_classes
24
+ [].tap do |classes|
25
+ classes << 'btn-close'
26
+ classes << bs_class
27
+ end.join(' ').strip
28
+ end
29
+
30
+ end
@@ -0,0 +1,84 @@
1
+ import * as bootstrap from 'bootstrap'
2
+
3
+ MatestackUiCore.Vue.component('matestack-ui-bootstrap-collapse', {
4
+ mixins: [MatestackUiCore.componentMixin],
5
+ data() {
6
+ return {
7
+ collapseInstance: undefined
8
+ };
9
+ },
10
+
11
+ methods: {
12
+ toggle: function (){
13
+ const self = this;
14
+ self.collapseInstance.toggle();
15
+ },
16
+ show: function(){
17
+ const self = this;
18
+ self.collapseInstance.show();
19
+ },
20
+ hide: function(){
21
+ const self = this;
22
+ self.collapseInstance.hide();
23
+ },
24
+ dispose: function(){
25
+ const self = this;
26
+ self.collapseInstance.hide();
27
+ self.collapseInstance.dispose();
28
+ // ToDo: Error occurs after dispose when click on the button again
29
+ }
30
+ },
31
+
32
+ mounted: function() {
33
+ const self = this;
34
+ var myCollapse = self.$el;
35
+ self.collapseInstance = new bootstrap.Collapse(myCollapse, {
36
+ toggle: false
37
+ })
38
+ },
39
+
40
+ created: function() {
41
+ const self = this
42
+
43
+ // toggle_on event registration
44
+ if(self.componentConfig["toggle_on"] != undefined){
45
+ var toggle_events = self.componentConfig["toggle_on"].split(",")
46
+ toggle_events.forEach(toggle_event => MatestackUiCore.matestackEventHub.$on(toggle_event.trim(), self.toggle));
47
+ }
48
+ // show_on event registration
49
+ if(self.componentConfig["show_on"] != undefined){
50
+ var show_events = self.componentConfig["show_on"].split(",")
51
+ show_events.forEach(show_event => MatestackUiCore.matestackEventHub.$on(show_event.trim(), self.show));
52
+ }
53
+ // hide_on event registration
54
+ if(self.componentConfig["hide_on"] != undefined){
55
+ var hide_events = self.componentConfig["hide_on"].split(",")
56
+ hide_events.forEach(hide_event => MatestackUiCore.matestackEventHub.$on(hide_event.trim(), self.hide));
57
+ }
58
+ // dispose_on event registration
59
+ if(self.componentConfig["dispose_on"] != undefined){
60
+ var dispose_events = self.componentConfig["dispose_on"].split(",")
61
+ dispose_events.forEach(dispose_event => MatestackUiCore.matestackEventHub.$on(dispose_event.trim(), self.dispose));
62
+ }
63
+ },
64
+
65
+ beforeDestroy: function(){
66
+ const self = this
67
+ if(self.componentConfig["toggle_on"] != undefined){
68
+ var show_events = self.componentConfig["toggle_on"].split(",")
69
+ show_events.forEach(show_event => MatestackUiCore.matestackEventHub.$off(show_event.trim(), self.show));
70
+ }
71
+ if(self.componentConfig["show_on"] != undefined){
72
+ var show_events = self.componentConfig["show_on"].split(",")
73
+ show_events.forEach(show_event => MatestackUiCore.matestackEventHub.$off(show_event.trim(), self.show));
74
+ }
75
+ if(self.componentConfig["hide_on"] != undefined){
76
+ var hide_events = self.componentConfig["hide_on"].split(",")
77
+ hide_events.forEach(hide_event => MatestackUiCore.matestackEventHub.$off(hide_event.trim(), self.hide));
78
+ }
79
+ if(self.componentConfig["dispose_on"] != undefined){
80
+ var dispose_events = self.componentConfig["dispose_on"].split(",")
81
+ dispose_events.forEach(dispose_event => MatestackUiCore.matestackEventHub.$off(dispose_event.trim(), self.dispose));
82
+ }
83
+ }
84
+ });
@@ -0,0 +1,43 @@
1
+ class Matestack::Ui::Bootstrap::Components::Collapse < Matestack::Ui::VueJsComponent
2
+ vue_js_component_name "matestack-ui-bootstrap-collapse"
3
+
4
+ optional :multi, :labelledby, :parent, class: { as: :bs_class }
5
+ optional :card # possible keys: class, text
6
+ # event trigger
7
+ optional :toggle_on, :show_on, :hide_on, :dispose_on
8
+
9
+ def response
10
+ div collapse_attributes do
11
+ card_partial if card
12
+ yield_components
13
+ end
14
+ end
15
+
16
+ protected
17
+
18
+ def card_partial
19
+ tmp_card = card.is_a?(Hash) ? self.card : { text: self.card }
20
+ div class: "card card-body #{tmp_card[:class]}".strip do
21
+ plain tmp_card[:text]
22
+ end
23
+ end
24
+
25
+ def collapse_attributes
26
+ html_attributes.merge(
27
+ class: collapse_classes,
28
+ data: { parent: parent },
29
+ attributes: { 'aria-labelledby': "#{labelledby}" }
30
+ )
31
+ end
32
+
33
+ def collapse_classes
34
+ [].tap do |classes|
35
+ classes << 'collapse'
36
+ # mulit target
37
+ classes << 'multi-collapse' if multi
38
+ #custom classes
39
+ classes << bs_class
40
+ end.join(' ').strip
41
+ end
42
+
43
+ end
@@ -0,0 +1,14 @@
1
+ import * as bootstrap from 'bootstrap'
2
+
3
+ MatestackUiCore.Vue.component('matestack-ui-bootstrap-dropdown', {
4
+ mixins: [MatestackUiCore.componentMixin],
5
+ data() {
6
+ return {
7
+ dropdownInstance: undefined
8
+ };
9
+ },
10
+ mounted() {
11
+ // var mydropdown = document.getElementById(this.componentConfig["dropdown-id"])
12
+ // this.dropdownInstance = new bootstrap.Dropdown(mydropdown)
13
+ }
14
+ });
@@ -0,0 +1,116 @@
1
+ class Matestack::Ui::Bootstrap::Components::Dropdown < Matestack::Ui::VueJsComponent
2
+ vue_js_component_name "matestack-ui-bootstrap-dropdown"
3
+
4
+ optional :variant, :text, :btn_class # button attributes
5
+ optional :direction, :align, :offset, :reference
6
+ # dropdown menu attributes, expects an array of items with possible keys: type, path, text
7
+ # or hash with possible keys: items, class
8
+ optional :menu
9
+ optional class: { as: :bs_class }, id: { as: :bs_id }, data: { as: :bs_data }
10
+ optional :slots
11
+ optional :size
12
+
13
+ def prepare
14
+ @bs_menu = self.menu.is_a?(Hash) ? self.menu : { items: self.menu }
15
+ end
16
+ def response
17
+ div dropdown_attributes do
18
+ split_btn_partial if slots && slots[:split_btn]
19
+ bs_btn btn_attributes unless slots && slots[:split_btn]
20
+
21
+ ul menu_attributes do
22
+ menu_partial unless @bs_menu[:items].blank?
23
+ yield_components
24
+ end
25
+ end
26
+ end
27
+
28
+ protected
29
+
30
+ def split_btn_partial
31
+ slot slots[:split_btn]
32
+ bs_btn btn_attributes do
33
+ span class:"sr-only" do plain "Toggle Dropdown" end
34
+ end
35
+ end
36
+
37
+ def menu_partial
38
+ @bs_menu[:items].each do |item|
39
+ case item[:type]
40
+ when :button
41
+ li do bs_btn item.merge(class: "dropdown-item #{item[:class]}") end
42
+ when :divider
43
+ li do hr class: "dropdown-divider" end
44
+ when :link
45
+ li do link item.merge(class: "dropdown-item #{item[:class]}") end
46
+ when :transition
47
+ li do transition item.merge(class: "dropdown-item #{item[:class]}") end
48
+ when :action
49
+ li do action item.merge(class: "dropdown-item #{item[:class]}") do plain item[:text] end end
50
+ else
51
+ span class: "dropdown-item-text" do plain item[:text] end
52
+ end
53
+ end
54
+ end
55
+
56
+ def dropdown_attributes
57
+ html_attributes.merge(
58
+ class: dropdown_classes
59
+ )
60
+ end
61
+
62
+ def dropdown_classes
63
+ [].tap do |classes|
64
+ classes << ((slots && slots[:split_btn]) ? 'btn-group' : 'dropdown')
65
+ classes << "drop#{direction}" if direction.present?
66
+ classes << bs_class
67
+ end.join(' ').strip
68
+ end
69
+
70
+ def btn_attributes
71
+ {
72
+ id: bs_id,
73
+ text: "#{text unless (slots && slots[:split_btn])}",
74
+ variant: (variant || :primary),
75
+ class: btn_classes,
76
+ data: btn_data,
77
+ size: size,
78
+ attributes: { 'aria-expanded': "false" }
79
+ }
80
+ end
81
+
82
+ def btn_data
83
+ (bs_data || {}).tap do |hash|
84
+ hash["bs-toggle"] = 'dropdown'
85
+ hash[:offset] = offset if offset.present?
86
+ hash[:reference] = reference if reference.present?
87
+ end
88
+ end
89
+
90
+ def btn_classes
91
+ [].tap do |classes|
92
+ classes << 'dropdown-toggle'
93
+ classes << 'dropdown-toggle-split' if slots && slots[:split_btn]
94
+ #custom classes
95
+ classes << btn_class
96
+ end.join(' ').strip
97
+ end
98
+
99
+ def menu_attributes
100
+ {
101
+ class: menu_classes,
102
+ data: { toggle: 'dropdown' },
103
+ attributes: { 'aria-labelledby': bs_id }
104
+ }
105
+ end
106
+
107
+ def menu_classes
108
+ [].tap do |classes|
109
+ classes << 'dropdown-menu'
110
+ classes << "dropdown-menu-#{align}" if align.present?
111
+ #custom classes
112
+ classes << @bs_menu[:class] if menu.is_a?(Hash)
113
+ end.join(' ').strip
114
+ end
115
+
116
+ end
@@ -0,0 +1,19 @@
1
+ class Matestack::Ui::Bootstrap::Components::Icon < Matestack::Ui::Component
2
+
3
+ requires :name
4
+ optional :size
5
+ optional class: { as: :bs_class }
6
+
7
+ def response
8
+ plain " <svg class='bi #{bs_class}' width='#{get_size}' height='#{get_size}' fill='currentColor'>
9
+ <use xlink:href='#{image_url("icons/bootstrap-icons.svg")}##{name}'/>
10
+ </svg>".html_safe
11
+ end
12
+
13
+ def get_size
14
+ size || 20
15
+ end
16
+
17
+
18
+
19
+ end
@@ -0,0 +1,83 @@
1
+ class Matestack::Ui::Bootstrap::Components::ListGroup < Matestack::Ui::Component
2
+ html_attributes :role
3
+
4
+ # optional :id
5
+ optional :items
6
+ optional :horizontal, :horizontal_size, :checkbox
7
+ optional :flush, :tablist, class: { as: :bs_class }
8
+
9
+
10
+ def response
11
+ ul list_group_attributes do
12
+ yield_components unless items
13
+ list_partial if items
14
+ end
15
+ end
16
+
17
+ protected
18
+
19
+ def list_partial
20
+ items.each do |item|
21
+ case item[:type]
22
+ when :link
23
+ link link_attrs(item) do
24
+ plain item[:text]
25
+ end
26
+ when :transition
27
+ transition link_attrs(item) do
28
+ plain item[:text]
29
+ end
30
+ when :label
31
+ label id: item[:id], class: "#{list_classes item, false}" do
32
+ input class: "form-check-input me-1", attributes: { 'type': "checkbox", 'value': "" } if checkbox
33
+ plain item[:text]
34
+ end
35
+ else
36
+ li id: item[:id], class: "#{list_classes item, false}" do
37
+ input class: "form-check-input me-1", attributes: { 'type': "checkbox", 'value': "", 'aria-label': "#{item[:text]}" } if checkbox
38
+ plain item[:text]
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ def list_group_attributes
45
+ attributes = {}.tap do |hash|
46
+ hash[:class] = list_group_classes
47
+ hash[:attributes] = { role: "tablist" } if tablist
48
+ end
49
+ html_attributes.merge(
50
+ attributes
51
+ )
52
+ end
53
+
54
+ def list_group_classes
55
+ [].tap do |classes|
56
+ classes << 'list-group'
57
+ classes << (horizontal_size.present? ? "list-group-horizontal-#{horizontal_size}": "list-group-horizontal") if horizontal
58
+ classes << 'list-group-flush' if flush
59
+ classes << bs_class
60
+ end.join(' ').strip
61
+ end
62
+
63
+ def link_attrs(item)
64
+ {}.tap do |hash|
65
+ hash[:id] = item[:id]
66
+ hash[:class] = "#{list_classes item, true}"
67
+ hash[:data] = { toggle: "list" } if tablist
68
+ hash[:attributes] = { 'aria-controls': "#{id}", role: "tab" } if tablist
69
+ hash[:path] = item[:path]
70
+ end
71
+ end
72
+
73
+ def list_classes(item, action)
74
+ [].tap do |classes|
75
+ classes << 'list-group-item'
76
+ classes << 'list-group-item-action' if action
77
+ classes << "list-group-item-#{item[:variant]}" if item[:variant].present?
78
+ classes << 'active' if item[:active]
79
+ classes << item[:class]
80
+ end.join(' ').strip
81
+ end
82
+
83
+ end