matestack-ui-bootstrap 1.4.0

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