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.
- checksums.yaml +7 -0
- data/LICENSE +8 -0
- data/README.md +26 -0
- data/Rakefile +43 -0
- data/app/assets/images/avatar-placeholder.png +0 -0
- data/app/assets/images/icons/bootstrap-icons.svg +1 -0
- data/app/concepts/matestack/ui/bootstrap/apps/admin_template.rb +85 -0
- data/app/concepts/matestack/ui/bootstrap/components/accordion.rb +53 -0
- data/app/concepts/matestack/ui/bootstrap/components/alert.js +53 -0
- data/app/concepts/matestack/ui/bootstrap/components/alert.rb +34 -0
- data/app/concepts/matestack/ui/bootstrap/components/avatar.rb +27 -0
- data/app/concepts/matestack/ui/bootstrap/components/badge.rb +30 -0
- data/app/concepts/matestack/ui/bootstrap/components/breadcrumb.rb +46 -0
- data/app/concepts/matestack/ui/bootstrap/components/button.rb +54 -0
- data/app/concepts/matestack/ui/bootstrap/components/button_group.rb +36 -0
- data/app/concepts/matestack/ui/bootstrap/components/card.rb +100 -0
- data/app/concepts/matestack/ui/bootstrap/components/carousel.js +79 -0
- data/app/concepts/matestack/ui/bootstrap/components/carousel.rb +85 -0
- data/app/concepts/matestack/ui/bootstrap/components/chart.js +232 -0
- data/app/concepts/matestack/ui/bootstrap/components/chart.rb +71 -0
- data/app/concepts/matestack/ui/bootstrap/components/close.rb +30 -0
- data/app/concepts/matestack/ui/bootstrap/components/collapse.js +84 -0
- data/app/concepts/matestack/ui/bootstrap/components/collapse.rb +43 -0
- data/app/concepts/matestack/ui/bootstrap/components/dropdown.js +14 -0
- data/app/concepts/matestack/ui/bootstrap/components/dropdown.rb +116 -0
- data/app/concepts/matestack/ui/bootstrap/components/icon.rb +19 -0
- data/app/concepts/matestack/ui/bootstrap/components/list_group.rb +83 -0
- data/app/concepts/matestack/ui/bootstrap/components/modal.js +90 -0
- data/app/concepts/matestack/ui/bootstrap/components/modal.rb +106 -0
- data/app/concepts/matestack/ui/bootstrap/components/navbar.rb +120 -0
- data/app/concepts/matestack/ui/bootstrap/components/page_heading.rb +28 -0
- data/app/concepts/matestack/ui/bootstrap/components/pagination.rb +40 -0
- data/app/concepts/matestack/ui/bootstrap/components/popover.js +26 -0
- data/app/concepts/matestack/ui/bootstrap/components/popover.rb +92 -0
- data/app/concepts/matestack/ui/bootstrap/components/progress.rb +65 -0
- data/app/concepts/matestack/ui/bootstrap/components/scrollspy.rb +33 -0
- data/app/concepts/matestack/ui/bootstrap/components/section_card.rb +31 -0
- data/app/concepts/matestack/ui/bootstrap/components/spinner.rb +31 -0
- data/app/concepts/matestack/ui/bootstrap/components/tab_nav.rb +81 -0
- data/app/concepts/matestack/ui/bootstrap/components/tab_nav_content.rb +32 -0
- data/app/concepts/matestack/ui/bootstrap/components/toast.js +79 -0
- data/app/concepts/matestack/ui/bootstrap/components/toast.rb +99 -0
- data/app/concepts/matestack/ui/bootstrap/components/tooltip.js +26 -0
- data/app/concepts/matestack/ui/bootstrap/components/tooltip.rb +82 -0
- data/app/concepts/matestack/ui/bootstrap/content/collection/collection.rb +112 -0
- data/app/concepts/matestack/ui/bootstrap/content/collection/collection.scss +10 -0
- data/app/concepts/matestack/ui/bootstrap/content/collection/content.rb +101 -0
- data/app/concepts/matestack/ui/bootstrap/content/collection/filter.rb +33 -0
- data/app/concepts/matestack/ui/bootstrap/content/collection/paginate.rb +92 -0
- data/app/concepts/matestack/ui/bootstrap/content/figure.rb +7 -0
- data/app/concepts/matestack/ui/bootstrap/form/checkbox.rb +90 -0
- data/app/concepts/matestack/ui/bootstrap/form/date.js +38 -0
- data/app/concepts/matestack/ui/bootstrap/form/date.rb +98 -0
- data/app/concepts/matestack/ui/bootstrap/form/input.rb +123 -0
- data/app/concepts/matestack/ui/bootstrap/form/radio.rb +65 -0
- data/app/concepts/matestack/ui/bootstrap/form/select.haml +11 -0
- data/app/concepts/matestack/ui/bootstrap/form/select.rb +74 -0
- data/app/concepts/matestack/ui/bootstrap/form/submit.rb +20 -0
- data/app/concepts/matestack/ui/bootstrap/form/switch.rb +90 -0
- data/app/concepts/matestack/ui/bootstrap/layout/column.rb +47 -0
- data/app/concepts/matestack/ui/bootstrap/layout/container.rb +25 -0
- data/app/concepts/matestack/ui/bootstrap/layout/row.rb +15 -0
- data/app/concepts/matestack/ui/bootstrap/layout/sidebar.js +64 -0
- data/app/concepts/matestack/ui/bootstrap/layout/sidebar.rb +45 -0
- data/app/concepts/matestack/ui/bootstrap/layout/sidebar.scss +57 -0
- data/app/concepts/matestack/ui/bootstrap/pages/devise/sign_in.rb +40 -0
- data/app/concepts/matestack/ui/bootstrap/registry.rb +63 -0
- data/app/helpers/matestack/ui/bootstrap/application_helper.rb +13 -0
- data/app/javascript/matestack-ui-bootstrap/index.js +26 -0
- data/app/javascript/matestack-ui-bootstrap/stylesheets/matestack-ui-bootstrap.scss +65 -0
- data/app/javascript/packs/matestack-ui-bootstrap.js +2 -0
- data/config/routes.rb +2 -0
- data/config/webpack/development.js +5 -0
- data/config/webpack/environment.js +29 -0
- data/config/webpack/production.js +33 -0
- data/config/webpack/test.js +5 -0
- data/config/webpacker.yml +96 -0
- data/lib/matestack/ui/bootstrap.rb +27 -0
- data/lib/matestack/ui/bootstrap/engine.rb +26 -0
- data/lib/matestack/ui/bootstrap/version.rb +7 -0
- data/lib/tasks/matestack/ui/bootstrap_tasks.rake +66 -0
- metadata +137 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as bootstrap from 'bootstrap'
|
|
2
|
+
|
|
3
|
+
MatestackUiCore.Vue.component('matestack-ui-bootstrap-modal', {
|
|
4
|
+
mixins: [MatestackUiCore.componentMixin],
|
|
5
|
+
|
|
6
|
+
data() {
|
|
7
|
+
return {
|
|
8
|
+
modalInstance: undefined,
|
|
9
|
+
};
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
methods: {
|
|
13
|
+
toggle: function (){
|
|
14
|
+
this.modalInstance.toggle()
|
|
15
|
+
},
|
|
16
|
+
show: function (){
|
|
17
|
+
this.modalInstance.show()
|
|
18
|
+
},
|
|
19
|
+
hide: function (){
|
|
20
|
+
this.modalInstance.hide()
|
|
21
|
+
},
|
|
22
|
+
handleUpdate: function (){
|
|
23
|
+
this.modalInstance.handleUpdate()
|
|
24
|
+
},
|
|
25
|
+
dispose: function (){
|
|
26
|
+
this.modalInstance.dispose()
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
mounted: function() {
|
|
31
|
+
const self = this
|
|
32
|
+
var modal = self.$el
|
|
33
|
+
self.modalInstance = new bootstrap.Modal(modal)
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
created: function() {
|
|
37
|
+
const self = this
|
|
38
|
+
var eventHub = MatestackUiCore.matestackEventHub;
|
|
39
|
+
// toggle_on event registration
|
|
40
|
+
if(self.componentConfig["toggle_on"] != undefined){
|
|
41
|
+
var toggle_events = self.componentConfig["toggle_on"].split(",")
|
|
42
|
+
toggle_events.forEach(toggle_event => eventHub.$on(toggle_event.trim(), self.toggle));
|
|
43
|
+
}
|
|
44
|
+
// show_on event registration
|
|
45
|
+
if(self.componentConfig["show_on"] != undefined){
|
|
46
|
+
var show_events = self.componentConfig["show_on"].split(",")
|
|
47
|
+
show_events.forEach(show_event => eventHub.$on(show_event.trim(), self.show));
|
|
48
|
+
}
|
|
49
|
+
// hide_on event registration
|
|
50
|
+
if(self.componentConfig["hide_on"] != undefined){
|
|
51
|
+
var hide_events = self.componentConfig["hide_on"].split(",")
|
|
52
|
+
hide_events.forEach(hide_event => eventHub.$on(hide_event.trim(), self.hide));
|
|
53
|
+
}
|
|
54
|
+
// handle_update_on event registration
|
|
55
|
+
if(self.componentConfig["handle_update_on"] != undefined){
|
|
56
|
+
var handle_update_events = self.componentConfig["handle_update_on"].split(",")
|
|
57
|
+
handle_update_events.forEach(handle_update_event => eventHub.$on(handle_update_event.trim(), self.handle_update));
|
|
58
|
+
}
|
|
59
|
+
// dispose_on event registration
|
|
60
|
+
if(self.componentConfig["dispose_on"] != undefined){
|
|
61
|
+
var dispose_events = self.componentConfig["dispose_on"].split(",")
|
|
62
|
+
dispose_events.forEach(dispose_event => eventHub.$on(dispose_event.trim(), self.dispose));
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
beforeDestroy: function() {
|
|
67
|
+
const self = this
|
|
68
|
+
var eventHub = MatestackUiCore.matestackEventHub;
|
|
69
|
+
if(self.componentConfig["toggle_on"] != undefined){
|
|
70
|
+
var toggle_events = self.componentConfig["toggle_on"].split(",")
|
|
71
|
+
toggle_events.forEach(toggle_event => eventHub.$off(toggle_event.trim(), self.toggle));
|
|
72
|
+
}
|
|
73
|
+
if(self.componentConfig["show_on"] != undefined){
|
|
74
|
+
var show_events = self.componentConfig["show_on"].split(",")
|
|
75
|
+
show_events.forEach(show_event => eventHub.$off(show_event.trim(), self.show));
|
|
76
|
+
}
|
|
77
|
+
if(self.componentConfig["hide_on"] != undefined){
|
|
78
|
+
var hide_events = self.componentConfig["hide_on"].split(",")
|
|
79
|
+
hide_events.forEach(hide_event => eventHub.$off(hide_event.trim(), self.hide));
|
|
80
|
+
}
|
|
81
|
+
if(self.componentConfig["handle_update_on"] != undefined){
|
|
82
|
+
var handle_update_events = self.componentConfig["handle_update_on"].split(",")
|
|
83
|
+
handle_update_events.forEach(handle_update_event => eventHub.$off(handle_update_event.trim(), self.handle_update));
|
|
84
|
+
}
|
|
85
|
+
if(self.componentConfig["dispose_on"] != undefined){
|
|
86
|
+
var dispose_events = self.componentConfig["dispose_on"].split(",")
|
|
87
|
+
dispose_events.forEach(dispose_event => eventHub.$off(dispose_event.trim(), self.dispose));
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
});
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
class Matestack::Ui::Bootstrap::Components::Modal < Matestack::Ui::VueJsComponent
|
|
2
|
+
vue_js_component_name 'matestack-ui-bootstrap-modal'
|
|
3
|
+
|
|
4
|
+
# header attributes, expects a hash or string
|
|
5
|
+
# possible keys `:class, :text, :size`
|
|
6
|
+
optional :header
|
|
7
|
+
# body attributes, expects a hash or string
|
|
8
|
+
# possible keys `:class, :text`
|
|
9
|
+
optional :body
|
|
10
|
+
# footer is a dismiss button, expects a hash or string for button text
|
|
11
|
+
# possible keys `:class, :text`
|
|
12
|
+
optional :footer
|
|
13
|
+
optional :fade, :size
|
|
14
|
+
optional :fullscreen # fullscreen attribute, expects boolean or bootstrap breakpoint
|
|
15
|
+
optional :static, :keyboard, :scrollable, :centered
|
|
16
|
+
optional :modal_dialog_class, class: { as: :bs_class }, id: { as: :bs_id }
|
|
17
|
+
# event trigger
|
|
18
|
+
optional :toggle_on, :show_on, :hide_on, :handle_update_on, :dispose_on
|
|
19
|
+
|
|
20
|
+
optional :slots
|
|
21
|
+
|
|
22
|
+
def response
|
|
23
|
+
div modal_attributes do
|
|
24
|
+
div class: dialog_classes do
|
|
25
|
+
div class: "modal-content" do
|
|
26
|
+
header_partial if header || (slots && slots[:header])
|
|
27
|
+
body_partial if body || slots && slots[:body]
|
|
28
|
+
footer_partial if footer || (slots && slots[:footer])
|
|
29
|
+
yield_components
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
protected
|
|
36
|
+
|
|
37
|
+
def header_partial
|
|
38
|
+
header = self.header.is_a?(Hash) ? self.header : { text: self.header }
|
|
39
|
+
div class: "modal-header" do
|
|
40
|
+
if slots && slots[:header]
|
|
41
|
+
slot slots[:header]
|
|
42
|
+
else
|
|
43
|
+
heading size: (header[:size] || 5), class: "modal-title #{header[:class]}", text: header[:text] if header[:text].present?
|
|
44
|
+
bs_close dismiss: 'modal'
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def body_partial
|
|
50
|
+
body = self.body.is_a?(Hash) ? self.body : { text: self.body }
|
|
51
|
+
div class: "modal-body #{body[:class]}".strip do
|
|
52
|
+
if slots && slots[:body]
|
|
53
|
+
slot slots[:body]
|
|
54
|
+
else
|
|
55
|
+
plain body[:text] if body[:text].present?
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def footer_partial
|
|
61
|
+
footer = self.footer.is_a?(Hash) ? self.footer : { text: self.footer }
|
|
62
|
+
div class: "modal-footer" do
|
|
63
|
+
slot slots[:footer] if slots && slots[:footer]
|
|
64
|
+
if footer[:text].present?
|
|
65
|
+
button class: "btn #{footer[:class].present? ? footer[:class] : 'btn-secondary'}",
|
|
66
|
+
data: { dismiss: 'modal' }, attributes: { type: 'button' },
|
|
67
|
+
text: footer[:text]
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def modal_attributes
|
|
73
|
+
attributes = {}.tap do |hash|
|
|
74
|
+
hash[:class] = modal_classes
|
|
75
|
+
hash[:attributes] = { 'tabindex': "-1", 'aria-labelledby': "#{bs_id}Label", 'aria-hidden': "true" }
|
|
76
|
+
hash[:data] = {}.tap do |data|
|
|
77
|
+
data[:backdrop] = "static" if static
|
|
78
|
+
data[:keyboard] = "false" if keyboard
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
html_attributes.merge(
|
|
82
|
+
attributes
|
|
83
|
+
)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def modal_classes
|
|
87
|
+
[].tap do |classes|
|
|
88
|
+
classes << 'modal'
|
|
89
|
+
classes << 'fade' if fade || !fade.present?
|
|
90
|
+
classes << bs_class
|
|
91
|
+
end.join(' ').strip
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def dialog_classes
|
|
95
|
+
[].tap do |classes|
|
|
96
|
+
classes << 'modal-dialog'
|
|
97
|
+
classes << 'modal-dialog-centered' if centered
|
|
98
|
+
classes << 'modal-dialog-scrollable' if scrollable
|
|
99
|
+
classes << "modal-#{size}" if size
|
|
100
|
+
if fullscreen.present?
|
|
101
|
+
classes << (fullscreen == true ? 'modal-fullscreen' : "modal-fullscreen-#{fullscreen}-down")
|
|
102
|
+
end
|
|
103
|
+
classes << modal_dialog_class
|
|
104
|
+
end.join(' ').strip
|
|
105
|
+
end
|
|
106
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
class Matestack::Ui::Bootstrap::Components::Navbar < Matestack::Ui::Component
|
|
2
|
+
|
|
3
|
+
POS_ATTRIBUTES = %i[fixed_top fixed_bottom sticky_top]
|
|
4
|
+
optional *POS_ATTRIBUTES
|
|
5
|
+
|
|
6
|
+
optional class: { as: :bs_class }
|
|
7
|
+
optional :items, :items_class, :theme, :hide_at, :color, :container_size
|
|
8
|
+
optional :collapse_class
|
|
9
|
+
# brand expect hash or string, possible keys for hash: text, path, img
|
|
10
|
+
optional :brand
|
|
11
|
+
# toogle expect hash or a symbol (:left or :right),
|
|
12
|
+
# possible keys for hash: position, class
|
|
13
|
+
optional :toggle
|
|
14
|
+
|
|
15
|
+
def prepare
|
|
16
|
+
@toggle = self.toggle.is_a?(Hash) ? self.toggle : { position: self.toggle }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def response
|
|
20
|
+
nav navbar_attributes do
|
|
21
|
+
bs_container size: "#{container_size.present? ? container_size : "fluid" }" do
|
|
22
|
+
# custom elements for navbar
|
|
23
|
+
if options[:slots] && options[:slots][:custom_items]
|
|
24
|
+
slot options[:slots][:custom_items]
|
|
25
|
+
else
|
|
26
|
+
toggle_button if @toggle[:position] == :left
|
|
27
|
+
brand_partial
|
|
28
|
+
toggle_button if !@toggle[:position].present? || @toggle[:position] == :right
|
|
29
|
+
navbar_content_partial
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
protected
|
|
36
|
+
|
|
37
|
+
def brand_partial
|
|
38
|
+
brand = self.brand.is_a?(Hash) ? self.brand : { text: self.brand }
|
|
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]
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def navbar_content_partial
|
|
47
|
+
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]
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
yield_components
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def navbar_attributes
|
|
70
|
+
html_attributes.merge(
|
|
71
|
+
class: navbar_classes
|
|
72
|
+
)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def navbar_classes
|
|
76
|
+
[].tap do |classes|
|
|
77
|
+
classes << "navbar"
|
|
78
|
+
POS_ATTRIBUTES.each do |pos|
|
|
79
|
+
classes << "#{pos}".gsub('_','-') if self.send("#{pos}")
|
|
80
|
+
end
|
|
81
|
+
classes << "navbar-expand-#{ (hide_at.present? ? hide_at : "lg") }"
|
|
82
|
+
classes << "navbar-#{theme}" if theme.present?
|
|
83
|
+
classes << (color.present? ? "bg-#{color}" : "bg-#{theme}") if theme || color
|
|
84
|
+
classes << bs_class
|
|
85
|
+
end.join(' ').strip
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def toggle_button
|
|
89
|
+
button toggle_attributes do
|
|
90
|
+
bs_icon name: "list", size: 25, class: "text-muted"
|
|
91
|
+
end
|
|
92
|
+
# button toggle_attributes do
|
|
93
|
+
# span class: "navbar-toggler-icon"
|
|
94
|
+
# end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def toggle_attributes
|
|
98
|
+
toggle_classes = [].tap do |classes|
|
|
99
|
+
classes << 'd-lg-none'
|
|
100
|
+
classes << 'btn btn-link'
|
|
101
|
+
classes << "ms-auto" if @toggle[:position] == :right
|
|
102
|
+
classes << "me-auto" if @toggle[:position] == :left
|
|
103
|
+
classes << @toggle[:class] if @toggle[:class]
|
|
104
|
+
end.join(' ').strip
|
|
105
|
+
|
|
106
|
+
{}.tap do |hash|
|
|
107
|
+
hash[:class] = toggle_classes
|
|
108
|
+
hash[:data] = { toggle: 'collapse', target: '#matestackNavbarContent' }
|
|
109
|
+
hash[:attributes] = { 'aria-controls': 'matestackNavbarContent', 'aria-expanded': 'false', 'aria-label': 'Toggle navigation' }
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def items_classes
|
|
114
|
+
[].tap do |classes|
|
|
115
|
+
classes << 'navbar-nav'
|
|
116
|
+
classes << (items_class.present? ? items_class : "ms-auto mb-2 mb-lg-0")
|
|
117
|
+
# classes << "ms-auto" unless items_class.present?
|
|
118
|
+
end.join(' ').strip
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
class Matestack::Ui::Bootstrap::Components::PageHeading < Matestack::Ui::Component
|
|
2
|
+
|
|
3
|
+
optional :title, :subtitle, :icon
|
|
4
|
+
|
|
5
|
+
def response
|
|
6
|
+
section class: "mb-5" do
|
|
7
|
+
bs_row do
|
|
8
|
+
bs_col do
|
|
9
|
+
div class: "page-heading-heading" do
|
|
10
|
+
heading size: 2 do
|
|
11
|
+
bs_icon name: icon, size: "35" if icon.present?
|
|
12
|
+
plain title
|
|
13
|
+
end
|
|
14
|
+
heading size: 6, class: "text-muted" do
|
|
15
|
+
plain subtitle
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
bs_col md: 12, xl: 4, class: "text-xl-end mt-3" do
|
|
20
|
+
div class: "page-heading-actions text-xl-end" do
|
|
21
|
+
yield_components
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
class Matestack::Ui::Bootstrap::Components::Pagination < Matestack::Ui::Component
|
|
2
|
+
|
|
3
|
+
optional :aria_label, :size, class: { as: :bs_class }
|
|
4
|
+
optional :items
|
|
5
|
+
|
|
6
|
+
def response
|
|
7
|
+
nav pagination_attributes do
|
|
8
|
+
ul class: ul_classes do
|
|
9
|
+
if items.present?
|
|
10
|
+
items.each do |item|
|
|
11
|
+
li class: "page-item #{ 'active' if item[:active] }" do
|
|
12
|
+
if item[:type] == :link
|
|
13
|
+
link path: item[:path], text: item[:text], class: 'page-link'
|
|
14
|
+
else
|
|
15
|
+
transition path: item[:path], text: item[:text], class: 'page-link'
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
yield_components
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
protected
|
|
26
|
+
|
|
27
|
+
def pagination_attributes
|
|
28
|
+
html_attributes.merge(
|
|
29
|
+
attributes: { 'aria-label': "#{aria_label || 'Page navigation'}" }
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def ul_classes
|
|
34
|
+
[].tap do |classes|
|
|
35
|
+
classes << "pagination"
|
|
36
|
+
classes << "pagination-#{size}" if size.present?
|
|
37
|
+
end.join(' ').strip
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as bootstrap from 'bootstrap'
|
|
2
|
+
|
|
3
|
+
MatestackUiCore.Vue.component('matestack-ui-bootstrap-popover', {
|
|
4
|
+
|
|
5
|
+
mixins: [MatestackUiCore.componentMixin],
|
|
6
|
+
data() {
|
|
7
|
+
return {
|
|
8
|
+
popoverInstance: undefined
|
|
9
|
+
|
|
10
|
+
};
|
|
11
|
+
},
|
|
12
|
+
methods: {
|
|
13
|
+
|
|
14
|
+
},
|
|
15
|
+
mounted: function() {
|
|
16
|
+
const self = this;
|
|
17
|
+
var popover = self.$el
|
|
18
|
+
self.popoverInstance = new bootstrap.Popover(popover, {})
|
|
19
|
+
},
|
|
20
|
+
created: function() {
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
beforeDestroy: function() {
|
|
24
|
+
|
|
25
|
+
},
|
|
26
|
+
});
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
class Matestack::Ui::Bootstrap::Components::Popover < Matestack::Ui::VueJsComponent
|
|
2
|
+
vue_js_component_name "matestack-ui-bootstrap-popover"
|
|
3
|
+
|
|
4
|
+
# How i imagine using a popover
|
|
5
|
+
#
|
|
6
|
+
# popover content: 'A popover' do
|
|
7
|
+
# button text: 'Popover'
|
|
8
|
+
# end
|
|
9
|
+
# => <span data-toggle="popover" data-content="A Popover"><button>Popover</button></span>
|
|
10
|
+
#
|
|
11
|
+
# popover content: 'A popover', tag: :div do
|
|
12
|
+
# button text: 'Popover'
|
|
13
|
+
# end
|
|
14
|
+
# => <div data-toggle="popover" data-content="A Popover"><button>Popover</button></div>
|
|
15
|
+
#
|
|
16
|
+
# popover text: 'Popover', content: 'A popover', tag: :button # should be default
|
|
17
|
+
# => <button data-toggle="popover" data-content="A Popover">Popover</button>
|
|
18
|
+
#
|
|
19
|
+
# popover text: 'Popover', content: 'A popover', dismissible: true, tabindex: 2
|
|
20
|
+
# => <a tabindex="2" data-toggle="popover" data-content="A Popover" data-trigger="focus" role="button">Popover</a>
|
|
21
|
+
#
|
|
22
|
+
# popover text: 'Popover', content: 'A popover', tag: :a
|
|
23
|
+
# => <a data-toggle="popover" data-content="A Popover">Popover</a>
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
DATA_ALIAS_ATTRIBUTES = %i[container delay selector html template fallback_placement]
|
|
27
|
+
|
|
28
|
+
DATA_ALIAS_ATTRIBUTES.each do |attribute|
|
|
29
|
+
optional "#{attribute}": { as: :"bs_#{attribute}"}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# TODO:
|
|
33
|
+
# for security reasons the sanitize, sanitizeFn and whiteList options cannot be supplied using data attributes.
|
|
34
|
+
# sanitize sanitize_fn white_list
|
|
35
|
+
|
|
36
|
+
optional class: { as: :bs_class }
|
|
37
|
+
optional id: { as: :bs_id }
|
|
38
|
+
DATA_ATTRIBUTES = %i[tag content title text variant animation placement tabindex trigger boundary offset popper_config]
|
|
39
|
+
optional *DATA_ATTRIBUTES
|
|
40
|
+
# :tag # different element to apply: div, span, links, button, ...
|
|
41
|
+
# :content, :title # popover title and content strings
|
|
42
|
+
# :animation # boolean, default true
|
|
43
|
+
# :variant, :text # button styling & text
|
|
44
|
+
# :placement # placement direction as string
|
|
45
|
+
|
|
46
|
+
def response
|
|
47
|
+
if tag.present?
|
|
48
|
+
public_send(tag, popover_attributes) do
|
|
49
|
+
content_partial
|
|
50
|
+
end
|
|
51
|
+
else
|
|
52
|
+
btn popover_attributes do
|
|
53
|
+
content_partial
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
protected
|
|
59
|
+
|
|
60
|
+
def content_partial
|
|
61
|
+
plain text if text
|
|
62
|
+
yield_components unless text
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def popover_attributes
|
|
66
|
+
attributes = {}.tap do |hash|
|
|
67
|
+
hash[:class] = popover_classes
|
|
68
|
+
hash[:attributes] = { role: (text ? 'button': nil), title: "#{title}", tabindex: "#{tabindex}" }
|
|
69
|
+
hash[:data] = {}.tap do |data|
|
|
70
|
+
DATA_ALIAS_ATTRIBUTES.each do |attribute|
|
|
71
|
+
data["bs-#{attribute}"] = self.send(:"bs_#{attribute}") if self.send(:"bs_#{attribute}")
|
|
72
|
+
end
|
|
73
|
+
(DATA_ATTRIBUTES - [:tag, :text, :variant]).each do |attribute|
|
|
74
|
+
data["bs-#{attribute}"] = self.send(:"#{attribute}") if self.send(:"#{attribute}")
|
|
75
|
+
end
|
|
76
|
+
data["bs-toggle"] = "popover"
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
html_attributes.merge(
|
|
80
|
+
attributes
|
|
81
|
+
)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def popover_classes
|
|
85
|
+
[].tap do |classes|
|
|
86
|
+
classes << "d-inline-block" unless text
|
|
87
|
+
classes << "btn btn-#{variant}" if variant
|
|
88
|
+
classes << bs_class
|
|
89
|
+
end.join(' ').strip
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
end
|