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,65 @@
|
|
|
1
|
+
class Matestack::Ui::Bootstrap::Components::Progress < Matestack::Ui::Component
|
|
2
|
+
|
|
3
|
+
optional class: { as: :bs_class }
|
|
4
|
+
optional :text, :valuemin, :valuemax
|
|
5
|
+
# progress expects a number or a list containing hashes with at least a :value
|
|
6
|
+
# other options are :text, :class, :variant, :striped, :animated, :aria_valuenow
|
|
7
|
+
optional :progress
|
|
8
|
+
# :value
|
|
9
|
+
optional :variant, :striped, :animated, :height
|
|
10
|
+
|
|
11
|
+
def response
|
|
12
|
+
div progress_attributes do
|
|
13
|
+
progress = self.progress.is_a?(Array) ? self.progress : [{ value: self.progress || value, text: self.text }]
|
|
14
|
+
progress.each do |prog|
|
|
15
|
+
progress_bar(prog[:value], valuemin, valuemax,
|
|
16
|
+
text: prog[:text], klass: prog[:class], variant: prog[:variant] || variant,
|
|
17
|
+
striped: prog[:striped] || striped, animated: prog[:animated] || animated,
|
|
18
|
+
aria_valuenow: prog[:aria_valuenow]
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
yield_components
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
protected
|
|
26
|
+
|
|
27
|
+
def progress_attributes
|
|
28
|
+
attributes = {}.tap do |hash|
|
|
29
|
+
hash[:class] = "progress #{bs_class}".strip
|
|
30
|
+
hash[:attributes] = { style: "height: #{height}px;" } if height
|
|
31
|
+
end
|
|
32
|
+
html_attributes.merge(
|
|
33
|
+
attributes
|
|
34
|
+
)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def progress_bar(value, min, max, text: nil, klass: nil, variant: :primary, striped: false, animated: false, aria_valuenow: nil)
|
|
38
|
+
div progress_bar_attributes(value, klass, variant, striped, animated, aria_valuenow) do
|
|
39
|
+
plain text if text
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def progress_bar_attributes(value, klass, variant, striped, animated, aria_valuenow)
|
|
44
|
+
{
|
|
45
|
+
class: progress_bar_classes(klass, variant, striped, animated),
|
|
46
|
+
attributes: {
|
|
47
|
+
role: :progressbar,
|
|
48
|
+
style: "width: #{value.to_i > 0 ? value : 0}%;",
|
|
49
|
+
'aria-valuenow': aria_valuenow || value || 0,
|
|
50
|
+
'aria-valuemin': valuemin || 0,
|
|
51
|
+
'aria-valuemax': valuemax || 100
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def progress_bar_classes(klass, variant, striped, animated)
|
|
57
|
+
[].tap do |classes|
|
|
58
|
+
classes << 'progress-bar'
|
|
59
|
+
classes << "bg-#{variant || :primary}"
|
|
60
|
+
classes << "progress-bar-striped" if striped
|
|
61
|
+
classes << "progress-bar-animated" if animated
|
|
62
|
+
classes << klass
|
|
63
|
+
end.join(' ').strip
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
class Matestack::Ui::Bootstrap::Components::Scrollspy < Matestack::Ui::Component
|
|
2
|
+
|
|
3
|
+
optional :offset # pixel to offset from top, by default 10
|
|
4
|
+
optional method: { as: :bs_method} # find which section, by default auto
|
|
5
|
+
optional :target # scroll target id
|
|
6
|
+
optional class: { as: :bs_class} # adding custom class to scrollspy
|
|
7
|
+
|
|
8
|
+
def response
|
|
9
|
+
div scrollspy_attributes do
|
|
10
|
+
yield_components
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
protected
|
|
15
|
+
|
|
16
|
+
def scrollspy_attributes
|
|
17
|
+
attributes = {}.tap do |hash|
|
|
18
|
+
hash[:class] = scrollspy_classes
|
|
19
|
+
hash[:data] = { "bs-spy": "scroll", "bs-target": "#{target}" }
|
|
20
|
+
hash[:data].merge!("bs-offset": offset) if offset.present?
|
|
21
|
+
hash[:data].merge!("bs-method": :"#{bs_method}") if bs_method.present?
|
|
22
|
+
end
|
|
23
|
+
html_attributes.merge(
|
|
24
|
+
attributes
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def scrollspy_classes
|
|
29
|
+
[].tap do |classes|
|
|
30
|
+
classes << bs_class
|
|
31
|
+
end.join(' ').strip
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
class Matestack::Ui::Bootstrap::Components::SectionCard < Matestack::Ui::Component
|
|
2
|
+
|
|
3
|
+
optional :id, :title, :subtitle, :icon, :slots, :content_padding
|
|
4
|
+
|
|
5
|
+
def response
|
|
6
|
+
section id: :id, class: "section-card rounded shadow-sm mb-4 bg-white" do
|
|
7
|
+
div class: "d-flex flex-row justify-content-between" do
|
|
8
|
+
if title.present? || subtitle.present?
|
|
9
|
+
div class: "section-card-heading p-4" do
|
|
10
|
+
heading size: 5, class: "mb-0" do
|
|
11
|
+
bs_icon name: icon, size: "35" if icon.present?
|
|
12
|
+
plain title
|
|
13
|
+
end
|
|
14
|
+
small class: "text-muted" do
|
|
15
|
+
plain subtitle
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
if slots.present? && slots[:actions].present?
|
|
20
|
+
div class: "section-card-actions p-4" do
|
|
21
|
+
slot slots[:actions]
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
div class: "section-card-content #{'p-4' unless content_padding == false} #{'pt-1' if title || subtitle}" do
|
|
26
|
+
yield_components
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
class Matestack::Ui::Bootstrap::Components::Spinner < Matestack::Ui::Component
|
|
2
|
+
|
|
3
|
+
optional class: { as: :bs_class }
|
|
4
|
+
optional :kind, :variant, :size, :sr_only
|
|
5
|
+
|
|
6
|
+
def response
|
|
7
|
+
div spinner_attributes do
|
|
8
|
+
span class: "sr-only", text: sr_only
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
protected
|
|
13
|
+
|
|
14
|
+
def spinner_attributes
|
|
15
|
+
html_attributes.merge(
|
|
16
|
+
class: spinner_class,
|
|
17
|
+
attributes: { 'role': "status" }
|
|
18
|
+
)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def spinner_class
|
|
22
|
+
[].tap do |classes|
|
|
23
|
+
spinner_kind = kind || :border
|
|
24
|
+
classes << "spinner-#{spinner_kind}"
|
|
25
|
+
classes << "text-#{variant || 'primary'}"
|
|
26
|
+
classes << "spinner-#{spinner_kind}-sm" if size
|
|
27
|
+
#optional classes
|
|
28
|
+
classes << bs_class
|
|
29
|
+
end.join(' ').strip
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
class Matestack::Ui::Bootstrap::Components::TabNav < Matestack::Ui::Component
|
|
2
|
+
|
|
3
|
+
requires :id
|
|
4
|
+
|
|
5
|
+
optional :items, :variant, :fill, :justified, :vertical, :vertical_up_to_sm,
|
|
6
|
+
:vertical_up_to_md, :vertical_up_to_xl, :horizontal,
|
|
7
|
+
class: { as: :bs_class }, attributes: { as: :bs_attrs}
|
|
8
|
+
|
|
9
|
+
def response
|
|
10
|
+
ul nav_attributes do
|
|
11
|
+
nav_items_partial if items.present?
|
|
12
|
+
end
|
|
13
|
+
div class: "tab-content", id: "#{id}Content" do
|
|
14
|
+
yield_components
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
protected
|
|
19
|
+
|
|
20
|
+
def nav_items_partial
|
|
21
|
+
items.each do |item|
|
|
22
|
+
li class: "nav-item", attributes: { role: "presentation" } do
|
|
23
|
+
# '<a class="nav-link active" id="pills-home-tab" data-toggle="pill" href="#pills-home" role="tab" aria-controls="pills-home" aria-selected="true">Home</a>'
|
|
24
|
+
link class: "nav-link #{'active' if item[:active]}",
|
|
25
|
+
id: "tab-#{item[:id]}",
|
|
26
|
+
path: "#tab-#{item[:id]}-content",
|
|
27
|
+
attributes: {
|
|
28
|
+
role: "tab",
|
|
29
|
+
"aria-controls": "tab-#{item[:id]}",
|
|
30
|
+
"aria-selected": "#{'true' if item[:active]}",
|
|
31
|
+
"data-bs-toggle": "tab"
|
|
32
|
+
} do
|
|
33
|
+
bs_icon name: item[:icon], size: 20 if item[:icon]
|
|
34
|
+
span class: "#{'ps-3' if item[:icon]}", text: item[:text] if item[:text]
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def link_attrs path, active, disabled, delay=nil
|
|
41
|
+
{}.tap do |hash|
|
|
42
|
+
hash[:class] = "nav-link #{'active' if path == request.fullpath } #{'disabled' if disabled}"
|
|
43
|
+
|
|
44
|
+
hash[:attributes] = {}.tap do |hash|
|
|
45
|
+
hash[:'aria-selected'] = path == request.fullpath ? 'true' : 'false'
|
|
46
|
+
hash[:'aria-current'] = 'page' if active == true
|
|
47
|
+
hash[:'aria-disabled'] = 'true' if disabled
|
|
48
|
+
hash[:role] = "tab" if toggle.present?
|
|
49
|
+
hash[:'aria-controls'] = "#{path.gsub('#','')}" if toggle.present?
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
hash[:data] = { "bs-toggle": "pill" } if pills
|
|
53
|
+
hash[:data] = { "bs-toggle": "tab" } if tabs
|
|
54
|
+
hash[:path] = path
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def nav_attributes
|
|
59
|
+
html_attributes.merge(
|
|
60
|
+
id: id,
|
|
61
|
+
class: nav_classes,
|
|
62
|
+
attributes: { role: "tablist"}
|
|
63
|
+
)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def nav_classes
|
|
67
|
+
[].tap do |classes|
|
|
68
|
+
classes << 'nav'
|
|
69
|
+
classes << 'nav-tabs' if variant == :tabs || variant.nil?
|
|
70
|
+
classes << 'nav-pills' if variant == :pills
|
|
71
|
+
classes << 'nav-fill' if fill
|
|
72
|
+
classes << 'nav-justified' if justified
|
|
73
|
+
classes << 'flex-column' if vertical
|
|
74
|
+
classes << 'flex-column flex-sm-column flex-md-row' if vertical_up_to_sm
|
|
75
|
+
classes << 'flex-column flex-sm-column flex-md-column flex-lg-row' if vertical_up_to_md
|
|
76
|
+
classes << 'flex-column flex-sm-column flex-md-column flex-lg-column flex-xl-row' if vertical_up_to_xl
|
|
77
|
+
classes << "justify-content-#{horizontal}" if horizontal.present?
|
|
78
|
+
classes << bs_class
|
|
79
|
+
end.join(' ').strip
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
class Matestack::Ui::Bootstrap::Components::TabNavContent < Matestack::Ui::Component
|
|
2
|
+
|
|
3
|
+
requires :id
|
|
4
|
+
|
|
5
|
+
optional :tabs, :pills, :active, class: { as: :bs_class }, attributes: { as: :bs_attrs}
|
|
6
|
+
|
|
7
|
+
def response
|
|
8
|
+
div tab_content_attributes do
|
|
9
|
+
yield_components
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
protected
|
|
14
|
+
|
|
15
|
+
def tab_content_attributes
|
|
16
|
+
html_attributes.merge(
|
|
17
|
+
id: "tab-#{id}-content",
|
|
18
|
+
class: tab_content_classes,
|
|
19
|
+
attributes: { role: "tabpanel", "aria-labelledby": "tab-#{id}" }
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def tab_content_classes
|
|
24
|
+
[].tap do |classes|
|
|
25
|
+
classes << 'tab-pane'
|
|
26
|
+
classes << 'fade'
|
|
27
|
+
classes << 'show ' if active
|
|
28
|
+
classes << 'active' if active
|
|
29
|
+
classes << bs_class
|
|
30
|
+
end.join(' ').strip
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import * as bootstrap from 'bootstrap'
|
|
2
|
+
|
|
3
|
+
MatestackUiCore.Vue.component('matestack-ui-bootstrap-toast', {
|
|
4
|
+
|
|
5
|
+
mixins: [MatestackUiCore.componentMixin],
|
|
6
|
+
data() {
|
|
7
|
+
return {
|
|
8
|
+
toastsInstance: undefined,
|
|
9
|
+
eventData: {},
|
|
10
|
+
showing: false,
|
|
11
|
+
};
|
|
12
|
+
},
|
|
13
|
+
methods: {
|
|
14
|
+
show: function(event){
|
|
15
|
+
const self = this;
|
|
16
|
+
if(this.componentConfig["autohide"]){
|
|
17
|
+
setTimeout(function () {
|
|
18
|
+
self.showing = false;
|
|
19
|
+
}, 5000);
|
|
20
|
+
}
|
|
21
|
+
this.showing = true
|
|
22
|
+
this.eventData = event
|
|
23
|
+
},
|
|
24
|
+
hide: function(event){
|
|
25
|
+
const self = this;
|
|
26
|
+
this.showing = false
|
|
27
|
+
setTimeout(function () {
|
|
28
|
+
self.eventData = false;
|
|
29
|
+
}, 500);
|
|
30
|
+
},
|
|
31
|
+
dispose: function(){
|
|
32
|
+
const self = this;
|
|
33
|
+
self.toastsInstance.dispose()
|
|
34
|
+
self.toastsInstance = new bootstrap.Toast(self.$el)
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
mounted: function() {
|
|
38
|
+
const self = this;
|
|
39
|
+
var myToasts = self.$el
|
|
40
|
+
self.toastsInstance = new bootstrap.Toast(myToasts)
|
|
41
|
+
},
|
|
42
|
+
created: function() {
|
|
43
|
+
const self = this
|
|
44
|
+
|
|
45
|
+
if(this.componentConfig["show_on"] != undefined){
|
|
46
|
+
var show_events = this.componentConfig["show_on"].split(",")
|
|
47
|
+
show_events.forEach(show_event => MatestackUiCore.matestackEventHub.$on(show_event.trim(), self.show));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if(this.componentConfig["hide_on"] != undefined){
|
|
51
|
+
var show_events = this.componentConfig["hide_on"].split(",")
|
|
52
|
+
show_events.forEach(show_event => MatestackUiCore.matestackEventHub.$on(show_event.trim(), self.hide));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if(this.componentConfig["dispose_on"] != undefined){
|
|
56
|
+
var show_events = this.componentConfig["dispose_on"].split(",")
|
|
57
|
+
show_events.forEach(show_event => MatestackUiCore.matestackEventHub.$on(show_event.trim(), self.dispose));
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
beforeDestroy: function() {
|
|
62
|
+
const self = this
|
|
63
|
+
MatestackUiCore.matestackEventHub.$off(this.componentConfig["show_on"], self.show);
|
|
64
|
+
MatestackUiCore.matestackEventHub.$off(this.componentConfig["hide_on"], self.hide);
|
|
65
|
+
MatestackUiCore.matestackEventHub.$off(this.componentConfig["dispose_on"], self.hide);
|
|
66
|
+
if(this.componentConfig["show_on"] != undefined){
|
|
67
|
+
var shown_events = this.componentConfig["show_on"].split(",")
|
|
68
|
+
shown_events.forEach(show_event => MatestackUiCore.matestackEventHub.$off(show_event.trim(), self.show));
|
|
69
|
+
}
|
|
70
|
+
if(this.componentConfig["hide_on"] != undefined){
|
|
71
|
+
var hiden_events = this.componentConfig["hide_on"].split(",")
|
|
72
|
+
hiden_events.forEach(hide_event => MatestackUiCore.matestackEventHub.$off(hide_event.trim(), self.hide));
|
|
73
|
+
}
|
|
74
|
+
if(this.componentConfig["dispose_on"] != undefined){
|
|
75
|
+
var hiden_events = this.componentConfig["dispose_on"].split(",")
|
|
76
|
+
hiden_events.forEach(hide_event => MatestackUiCore.matestackEventHub.$off(hide_event.trim(), self.dispose));
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
});
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
class Matestack::Ui::Bootstrap::Components::Toast < Matestack::Ui::VueJsComponent
|
|
2
|
+
vue_js_component_name "matestack-ui-bootstrap-toast"
|
|
3
|
+
|
|
4
|
+
# header attributes, expects a hash or string
|
|
5
|
+
# possible keys `:icon_class, :icon, :title, :subtitle`
|
|
6
|
+
optional :header
|
|
7
|
+
# body expects a string as message inside toast
|
|
8
|
+
optional :body
|
|
9
|
+
# placement attributes, expects a hash wiht possible keys: position, min-height
|
|
10
|
+
optional :placement # for adding custom css style
|
|
11
|
+
optional :important, :delay, :autohide, :animation
|
|
12
|
+
optional class: { as: :bs_class }, attributes: { as: :bs_attrs }, data: { as: :bs_data }
|
|
13
|
+
optional :slots
|
|
14
|
+
|
|
15
|
+
def response
|
|
16
|
+
standard_placement_partial
|
|
17
|
+
# standard_placement_partial unless placement.present?
|
|
18
|
+
# custom_placement_partial if placement.present?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
protected
|
|
22
|
+
|
|
23
|
+
def custom_placement_partial
|
|
24
|
+
div attributes: placement_attrs do
|
|
25
|
+
standard_placement_partial
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def standard_placement_partial
|
|
30
|
+
div toast_attributes do
|
|
31
|
+
header_partial if header || slots && slots[:header]
|
|
32
|
+
body_partial
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def header_partial
|
|
37
|
+
header = self.header.is_a?(Hash) ? self.header : { title: self.header }
|
|
38
|
+
div class: "toast-header" do
|
|
39
|
+
img class: "#{'rounded me-2' || header[:icon_class]}", path: header[:icon] if header[:icon].present?
|
|
40
|
+
strong class: "me-auto", text: header[:title] if header[:title].present?
|
|
41
|
+
small text: header[:subtitle] if header[:subtitle].present?
|
|
42
|
+
|
|
43
|
+
slot slots[:header] if slots && slots[:header]
|
|
44
|
+
bs_close dismiss: 'toast', class: "ms-2 mb-1", attributes: { "@click": "hide()"}
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def body_partial
|
|
50
|
+
div class: "toast-body" do
|
|
51
|
+
plain body if body
|
|
52
|
+
end
|
|
53
|
+
unless header || slots && slots[:header]
|
|
54
|
+
bs_close dismiss: 'toast', class: "ms-auto me-2 btn-close-white", attributes: { "@click": "hide()"}
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def toast_attributes
|
|
59
|
+
html_attributes.merge(
|
|
60
|
+
class: toast_classes,
|
|
61
|
+
attributes: toast_attrs,
|
|
62
|
+
data: toast_data
|
|
63
|
+
)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def toast_data
|
|
67
|
+
(bs_data || {}).tap do |hash|
|
|
68
|
+
hash["bs-delay"] = delay.nil? ? 5000 : delay
|
|
69
|
+
hash["bs-autohide"] = autohide.nil? ? "true" : "#{autohide}"
|
|
70
|
+
hash["bs-animation"] = animation.nil? ? "true" : "#{animation}"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def toast_attrs
|
|
75
|
+
(bs_attrs || {}).tap do |hash|
|
|
76
|
+
hash[:role] = (important == false ? 'status' : 'alert')
|
|
77
|
+
hash[:'aria-live'] = (important ? 'assertive' : 'polite') if important.present? && !placement.present?
|
|
78
|
+
hash[:'aria-live'] = 'assertive' unless important.present?
|
|
79
|
+
hash[:'aria-atomic'] = 'true' unless placement.present?
|
|
80
|
+
hash[:style] = "z-index: 10000; position: fixed; #{placement[:position] || 'top: 0; right: 0;' }" if placement.present?
|
|
81
|
+
hash["v-bind:class"] = "{'show' : showing }"
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def toast_classes
|
|
86
|
+
[].tap do |classes|
|
|
87
|
+
classes << 'toast p-0 fade d-flex align-items-center border-0'
|
|
88
|
+
classes << bs_class
|
|
89
|
+
end.join(' ').strip
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def placement_attrs
|
|
93
|
+
{}.tap do |hash|
|
|
94
|
+
hash[:'aria-live'] = (important ? 'assertive' : 'polite') if important.present?
|
|
95
|
+
hash[:'aria-atomic'] = 'true'
|
|
96
|
+
hash[:style] = "position: relative; min-height: #{placement[:height]};"
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|