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
@@ -0,0 +1,113 @@
1
+ require_relative "../base_vue_js_component"
2
+
3
+ class Matestack::Ui::Bootstrap::Components::Toast < Matestack::Ui::Bootstrap::BaseVueJsComponent
4
+ vue_name "matestack-ui-bootstrap-toast"
5
+
6
+ # header attributes, expects a hash or string
7
+ # possible keys `:icon_class, :icon, :title, :subtitle`
8
+ optional :header
9
+ # body expects a string as message inside toast
10
+ optional :body
11
+ # placement attributes, expects a hash wiht possible keys: position, min-height
12
+ optional :placement # for adding custom css style
13
+ optional :important, :delay, :autohide, :animation
14
+ optional class: { as: :bs_class }
15
+ optional :attributes, :data
16
+
17
+
18
+ optional :show_on, :hide_on, :dispose_on
19
+
20
+ def response
21
+ standard_placement_partial
22
+ # standard_placement_partial unless placement.present?
23
+ # custom_placement_partial if placement.present?
24
+ end
25
+
26
+ protected
27
+
28
+ def vue_props
29
+ {}.tap do |props|
30
+ props[:delay] = context.delay
31
+ props[:autohide] = context.autohide
32
+ props[:show_on] = context.show_on
33
+ props[:hide_on] = context.hide_on
34
+ props[:dispose_on] = context.dispose_on
35
+ end
36
+ end
37
+
38
+ def custom_placement_partial
39
+ div placement_attrs do
40
+ standard_placement_partial
41
+ end
42
+ end
43
+
44
+ def standard_placement_partial
45
+ div toast_attributes do
46
+ header_partial if context.header || slots && slots[:header]
47
+ body_partial
48
+ end
49
+ end
50
+
51
+ def header_partial
52
+ header = context.header.is_a?(Hash) ? context.header : { title: context.header }
53
+ div class: "toast-header" do
54
+ img class: "#{'rounded me-2' || header[:icon_class]}", path: header[:icon] if header[:icon].present?
55
+ strong header[:title], class: "me-auto" if header[:title].present?
56
+ small header[:subtitle] if header[:subtitle].present?
57
+
58
+ slot :header if slots && slots[:header]
59
+ bs_close dismiss: 'toast', class: "ms-2 mb-1", "@click": "hide()"
60
+ end
61
+
62
+ end
63
+
64
+ def body_partial
65
+ div class: "toast-body" do
66
+ plain context.body if context.body
67
+ end
68
+ unless context.header || slots && slots[:header]
69
+ bs_close dismiss: 'toast', class: "ms-auto me-2 btn-close-white", "@click": "hide()"
70
+ end
71
+ end
72
+
73
+ def toast_attributes
74
+ options.merge(
75
+ class: toast_classes,
76
+ data: toast_data
77
+ ).merge(toast_attrs)
78
+ end
79
+
80
+ def toast_data
81
+ (context.data || {}).tap do |hash|
82
+ hash["bs-delay"] = context.delay.nil? ? 5000 : context.delay
83
+ hash["bs-autohide"] = context.autohide.nil? ? "true" : "#{context.autohide}"
84
+ hash["bs-animation"] = context.animation.nil? ? "true" : "#{context.animation}"
85
+ end
86
+ end
87
+
88
+ def toast_attrs
89
+ (context.attributes || {}).tap do |hash|
90
+ hash[:role] = (context.important == false ? 'status' : 'alert')
91
+ hash[:'aria-live'] = (context.important ? 'assertive' : 'polite') if context.important.present? && !context.placement.present?
92
+ hash[:'aria-live'] = 'assertive' unless context.important.present?
93
+ hash[:'aria-atomic'] = 'true' unless context.placement.present?
94
+ hash[:style] = "z-index: 10000; position: fixed; #{context.placement[:position] || 'top: 0; right: 0;' }" if context.placement.present?
95
+ hash[:"v-bind:class"] = "{'show' : showing }"
96
+ end
97
+ end
98
+
99
+ def toast_classes
100
+ [].tap do |classes|
101
+ classes << 'toast p-0 fade d-flex align-items-center border-0'
102
+ classes << context.bs_class
103
+ end.join(' ').strip
104
+ end
105
+
106
+ def placement_attrs
107
+ {}.tap do |hash|
108
+ hash[:'aria-live'] = (context.important ? 'assertive' : 'polite') if context.important.present?
109
+ hash[:'aria-atomic'] = 'true'
110
+ hash[:style] = "position: relative; min-height: #{context.placement[:height]};"
111
+ end
112
+ end
113
+ 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-tooltip', {
4
+ import MatestackUiCore from 'matestack-ui-core'
5
+
6
+ Vue.component('matestack-ui-bootstrap-tooltip', {
4
7
 
5
8
  mixins: [MatestackUiCore.componentMixin],
6
9
  data() {
@@ -0,0 +1,66 @@
1
+ require_relative "../base_vue_js_component"
2
+
3
+ class Matestack::Ui::Bootstrap::Components::Tooltip < Matestack::Ui::Bootstrap::BaseVueJsComponent
4
+ vue_name "matestack-ui-bootstrap-tooltip"
5
+
6
+ DATA_ALIAS_ATTRIBUTES = %i[container delay selector html template fallback_placement]
7
+
8
+ DATA_ALIAS_ATTRIBUTES.each do |attribute|
9
+ optional :"#{attribute}"
10
+ end
11
+
12
+ # TODO:
13
+ # for security reasons the sanitize, sanitizeFn and whiteList options cannot be supplied using data attributes.
14
+ # sanitize sanitize_fn white_list
15
+ # optional :content
16
+ required :tooltip_title
17
+ optional :tag
18
+ optional class: { as: :bs_class }
19
+ optional :id
20
+ DATA_ATTRIBUTES = %i[text variant animation placement tabindex trigger boundary offset popper_config]
21
+ optional *DATA_ATTRIBUTES
22
+
23
+ def response
24
+ case context.tag
25
+ when :div
26
+ div tooltip_attributes do
27
+ yield if block_given?
28
+ end
29
+ else
30
+ span tooltip_attributes do
31
+ yield if block_given?
32
+ end
33
+ end
34
+ end
35
+
36
+ protected
37
+
38
+ def tooltip_attributes
39
+ attributes = {}.tap do |hash|
40
+ hash[:class] = tooltip_classes
41
+ hash[:text] = context.text if context.text.present?
42
+ hash[:data] = {}.tap do |hash|
43
+ DATA_ALIAS_ATTRIBUTES.each do |attribute|
44
+ hash["bs-#{attribute}"] = context.send("#{attribute}") if context.send("#{attribute}")
45
+ end
46
+ DATA_ATTRIBUTES.each do |attribute|
47
+ hash["bs-#{attribute}"] = context.send("#{attribute}") if context.send("#{attribute}")
48
+ end
49
+ hash["bs-toggle"] = "tooltip"
50
+ hash["bs-type"] = context.tag
51
+ hash["bs-placement"] = "auto" if context.placement.nil?
52
+ hash["bs-title"] = context.tooltip_title
53
+ end
54
+ end
55
+ options.merge(
56
+ attributes || {}
57
+ )
58
+ end
59
+
60
+ def tooltip_classes
61
+ [].tap do |classes|
62
+ classes << context.bs_class
63
+ end.join(' ').strip
64
+ end
65
+
66
+ end
@@ -1,7 +1,9 @@
1
- class Matestack::Ui::Bootstrap::Content::Figure < Matestack::Ui::Component
1
+ require_relative "../base_component"
2
+
3
+ class Matestack::Ui::Bootstrap::Content::Figure < Matestack::Ui::Bootstrap::BaseComponent
2
4
 
3
5
  def response
4
6
  # provide a bootstrap figure
5
7
  end
6
8
 
7
- end
9
+ end
@@ -0,0 +1,120 @@
1
+ require_relative "../../base_component"
2
+
3
+ require_relative "./content"
4
+ require_relative "./filter"
5
+ require_relative "./paginate"
6
+
7
+ class Matestack::Ui::Bootstrap::Content::SmartCollection::Collection < Matestack::Ui::Bootstrap::BaseComponent
8
+ include Matestack::Ui::VueJs::Components::Collection::Helper
9
+ include Matestack::Ui::Bootstrap::Content::SmartCollection::Content
10
+ include Matestack::Ui::Bootstrap::Content::SmartCollection::Filter
11
+ include Matestack::Ui::Bootstrap::Content::SmartCollection::Paginate
12
+
13
+ # html attributes
14
+ optional :id
15
+
16
+ # table configuration
17
+ optional :items
18
+ optional :columns
19
+ optional :filters
20
+ optional :footer
21
+ optional :paginate
22
+ optional :rerender_on
23
+ optional :item_actions_proc
24
+ optional :collection_rendering_proc
25
+
26
+
27
+ # bootstrap settings
28
+ optional :responsive
29
+ optional :variant
30
+ optional :striped
31
+ optional :hoverable
32
+ optional :border_variant
33
+ optional :borderless
34
+
35
+ attr_accessor :processed_filters
36
+
37
+ def response
38
+ div id: context.id, class: "smart-collection" do
39
+ filter_partial
40
+ content
41
+ end
42
+ end
43
+
44
+
45
+ private
46
+
47
+ def collection
48
+ return @collection if @collection
49
+ settings = {}.tap do |h|
50
+ h[:id] = context.id || "smartcollection"
51
+ h[:data] = filtered_query
52
+ h[:base_count] = context.items.count
53
+ h[:init_limit] = context.paginate if context.paginate
54
+ h[:filtered_count] = filtered_query.count if context.paginate
55
+ end
56
+ @collection = set_collection(settings)
57
+ end
58
+
59
+ def collection_id
60
+ collection.config[:id]
61
+ end
62
+
63
+ def filtered_query
64
+ return @filtered_query if @filtered_query
65
+ @filtered_query = context.items
66
+ unless context.filters.nil?
67
+ context.filters.select { |key, value| '.'.in? key.to_s }.each do |key, value|
68
+ associated_name = key.to_s.split(".").first
69
+ @filtered_query = @filtered_query.joins(associated_name.to_sym).all
70
+ if value.is_a?(Hash)
71
+ processed_filters[key] = value
72
+ @filtered_query = add_query_filter(@filtered_query, associated_name, key, value)
73
+ end
74
+ end
75
+ context.filters.reject { |key, value| '.'.in? key.to_s }.each do |key, value|
76
+ if value.is_a?(Hash)
77
+ processed_filters[key] = value
78
+ @filtered_query = add_query_filter(@filtered_query, nil, key, value)
79
+ end
80
+ end
81
+ end
82
+ @filtered_query
83
+ end
84
+
85
+ def add_query_filter(query, associated_name, key, filter_config)
86
+ value = get_collection_filter(collection_id)[key.to_sym]
87
+ if value.present?
88
+ if associated_name.present?
89
+ table_name = context.items.klass.reflections[associated_name].table_name
90
+ key = key.to_s.gsub(associated_name, table_name)
91
+ else
92
+ table_name = context.items.klass.table_name
93
+ key = key.to_s
94
+ end
95
+ case filter_config[:match]
96
+ when :equals
97
+ query = query.where("#{key}": value)
98
+ when :starts_with
99
+ query = query.where("lower(#{key}) LIKE ?", "#{value.downcase}%")
100
+ when :ends_with
101
+ query = query.where("lower(#{key}) LIKE ?", "%#{value.downcase}")
102
+ when :like
103
+ query = query.where("lower(#{key}) LIKE ?", "%#{value.downcase}%")
104
+ else
105
+ query = query.where("#{key}": value)
106
+ end
107
+ end
108
+ query
109
+ end
110
+
111
+ def head_columns
112
+ context.columns.map { |key, value| value.is_a?(Hash) ? value[:heading] : value }
113
+ end
114
+
115
+ def processed_filters
116
+ @filters ||= {}
117
+ end
118
+
119
+
120
+ end
@@ -0,0 +1,118 @@
1
+ module Matestack::Ui::Bootstrap::Content::SmartCollection::Content
2
+
3
+ def content
4
+ bs_row class: 'smart-collection-content' do
5
+ bs_col do
6
+ async id: "#{collection_id}-async", rerender_on: "#{collection_id}-update, #{context.rerender_on} " do
7
+ collection_content collection.config do
8
+ div class: responsive_class do
9
+ if slots && slots[:collection_rendering]
10
+ slot :collection_rendering, collection.paginated_data
11
+ elsif context.columns
12
+ div class: "table-responsive" do
13
+ table table_attributes do
14
+ table_head
15
+ table_body
16
+ table_footer
17
+ end
18
+ end
19
+ end
20
+ end
21
+ paginate_partial if context.paginate.present?
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def table_head
29
+ thead do
30
+ tr do
31
+ context.columns&.each do |key, value|
32
+ th class: cell_class(value), scope: :col do
33
+ plain value.is_a?(Hash) ? value[:heading] : value
34
+ end
35
+ end
36
+ th if slots && slots[:table_item_actions]
37
+ end
38
+ end
39
+ end
40
+
41
+ def table_body
42
+ tbody do
43
+ collection.paginated_data.each_with_index do |data, index|
44
+ tr class: 'align-middle' do
45
+ context.columns.each do |key, value|
46
+ cell(data, key, value)
47
+ end
48
+ if slots && slots[:table_item_actions]
49
+ td class: 'text-end' do
50
+ slot :table_item_actions, data
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ def table_footer
59
+ tfoot do
60
+ tr do
61
+ context.footer&.each do |value|
62
+ td value
63
+ end
64
+ end
65
+ end if context.footer
66
+ end
67
+
68
+ private
69
+
70
+ def cell(data, key, value)
71
+ td class: cell_class(value) do
72
+ if value.is_a?(Hash) && value[:slot]
73
+ value[:slot].call(data)
74
+ else
75
+ plain cell_text(data, key, value)
76
+ end
77
+ end
78
+ end
79
+
80
+ def cell_class(value)
81
+ [].tap do |classes|
82
+ classes << "text-#{value[:text]}" if value[:text]
83
+ classes << "align-#{value[:align]}" if value[:align]
84
+ end.join(' ') if value.is_a? Hash
85
+ end
86
+
87
+ def cell_text(data, key, value)
88
+ if value.is_a?(Hash)
89
+ if value[:attribute].present?
90
+ text = data.instance_eval(value[:attribute].to_s)
91
+ else
92
+ text = data.instance_eval(key.to_s)
93
+ end
94
+ text = value[:format].call(text) if value[:format].present?
95
+ else
96
+ text = data.instance_eval(key.to_s)
97
+ end
98
+
99
+ text
100
+ end
101
+
102
+ def table_attributes
103
+ klass = ['table'].tap do |classes|
104
+ classes << "table-#{context.variant}" if context.variant
105
+ classes << "table-striped" if context.striped
106
+ classes << "table-hover" if context.hoverable
107
+ classes << "table-bordered border-#{context.border_variant}" if context.border_variant
108
+ classes << "table-borderless" if context.borderless
109
+ end.join(' ').strip
110
+ { id: collection_id, class: klass }
111
+ end
112
+
113
+ def responsive_class
114
+ return unless context.responsive
115
+ responsive === true ? 'table-responsive' : "table-responsive-#{context.responsive}"
116
+ end
117
+
118
+ end