matestack-ui-bootstrap 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +65 -7
  3. data/app/concepts/matestack/ui/bootstrap/components/accordion.rb +17 -14
  4. data/app/concepts/matestack/ui/bootstrap/components/alert.rb +1 -1
  5. data/app/concepts/matestack/ui/bootstrap/components/badge.rb +4 -4
  6. data/app/concepts/matestack/ui/bootstrap/components/breadcrumb.rb +8 -6
  7. data/app/concepts/matestack/ui/bootstrap/components/button.rb +18 -3
  8. data/app/concepts/matestack/ui/bootstrap/components/carousel.rb +15 -14
  9. data/app/concepts/matestack/ui/bootstrap/components/close.rb +1 -1
  10. data/app/concepts/matestack/ui/bootstrap/components/collapse.rb +6 -6
  11. data/app/concepts/matestack/ui/bootstrap/components/dropdown.rb +3 -2
  12. data/app/concepts/matestack/ui/bootstrap/components/list_group.rb +87 -25
  13. data/app/concepts/matestack/ui/bootstrap/components/modal.rb +1 -1
  14. data/app/concepts/matestack/ui/bootstrap/components/navbar.rb +54 -20
  15. data/app/concepts/matestack/ui/bootstrap/components/pagination.rb +5 -5
  16. data/app/concepts/matestack/ui/bootstrap/components/popover.rb +1 -1
  17. data/app/concepts/matestack/ui/bootstrap/components/progress.rb +7 -7
  18. data/app/concepts/matestack/ui/bootstrap/components/scrollspy.rb +15 -0
  19. data/app/concepts/matestack/ui/bootstrap/components/spinner.rb +1 -1
  20. data/app/concepts/matestack/ui/bootstrap/components/tab_nav.rb +4 -2
  21. data/app/concepts/matestack/ui/bootstrap/components/toast.js +7 -1
  22. data/app/concepts/matestack/ui/bootstrap/components/tooltip.rb +8 -26
  23. data/app/concepts/matestack/ui/bootstrap/content/{collection → smart_collection}/collection.rb +18 -16
  24. data/app/concepts/matestack/ui/bootstrap/content/{collection → smart_collection}/collection.scss +0 -0
  25. data/app/concepts/matestack/ui/bootstrap/content/{collection → smart_collection}/content.rb +3 -3
  26. data/app/concepts/matestack/ui/bootstrap/content/{collection → smart_collection}/filter.rb +3 -3
  27. data/app/concepts/matestack/ui/bootstrap/content/{collection → smart_collection}/paginate.rb +3 -3
  28. data/app/concepts/matestack/ui/bootstrap/form/checkbox.rb +55 -46
  29. data/app/concepts/matestack/ui/bootstrap/form/input.rb +5 -16
  30. data/app/concepts/matestack/ui/bootstrap/form/radio.rb +22 -30
  31. data/app/concepts/matestack/ui/bootstrap/form/select.rb +12 -33
  32. data/app/concepts/matestack/ui/bootstrap/form/submit.rb +3 -2
  33. data/app/concepts/matestack/ui/bootstrap/form/switch.rb +80 -71
  34. data/app/concepts/matestack/ui/bootstrap/registry.rb +2 -4
  35. data/app/helpers/matestack/ui/bootstrap/application_helper.rb +9 -5
  36. data/app/javascript/matestack-ui-bootstrap/index.js +1 -3
  37. data/app/matestack/bootstrap/form/submit.rb +20 -0
  38. data/lib/matestack/ui/bootstrap/engine.rb +2 -2
  39. data/lib/matestack/ui/bootstrap/version.rb +1 -1
  40. data/lib/tasks/matestack/ui/bootstrap_tasks.rake +25 -25
  41. metadata +8 -12
  42. data/app/concepts/matestack/ui/bootstrap/components/chart.js +0 -232
  43. data/app/concepts/matestack/ui/bootstrap/components/chart.rb +0 -71
  44. data/app/concepts/matestack/ui/bootstrap/form/date.js +0 -38
  45. data/app/concepts/matestack/ui/bootstrap/form/date.rb +0 -98
  46. data/app/concepts/matestack/ui/bootstrap/form/select.haml +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ba5c4e5ee5de8fa5f54ea36e927a971339b37c9b8db2a360543a01e77e134eb4
4
- data.tar.gz: b4c4d1c23cf14620a27b53de3ae53a05e6adc2ef4cbf010cd7c314bdcd503ed0
3
+ metadata.gz: '08d09d04a3fd7038133603a6e950ee7aa83903545028028eb518a05a60abf737'
4
+ data.tar.gz: 5a0bb2d33f779374a167658c884790adc87de8f7e7b9b28282e325b4d2d70ab0
5
5
  SHA512:
6
- metadata.gz: e62de426827277bbdf8a66de6f6290d0366d3da00a83d59a5d5503d6a548c3fc7d397c839661f91b80ace1e3d6e9bec646aab8277cf58b3ddc42c9aa6aa187d0
7
- data.tar.gz: 84ad2178a7652766cd265cfe7b768279d87583856a96e1771a5464f81b6b1e1d5300e25350a89e90de185bc4b55418894203eef596dd67f9a118ae5ced8cfa1b
6
+ metadata.gz: 725e1fda66e9ecc1fbc9aff03a235e009dbe2b81cdf0c5b0ef7f61a472bc573580b326ee8e63df784982a2f5265e7c92d12d3d083e3656c8a6341338b836dbe6
7
+ data.tar.gz: 24f136ee905fa88d41dcb48a92e311569ae5bbd212cd6b0a76bcae6df118e0b216c6551a6266dbd023bef11c79fd667191e984f3f5edb046537d252f2f6c9a28
data/README.md CHANGED
@@ -1,26 +1,84 @@
1
1
  # Matestack Ui Bootstrap
2
2
 
3
+ **Docs and specs in progress, please wait for official release announcement before using this gem**
3
4
 
4
- ## Develpment
5
+ ## Development
6
+
7
+ ### Dummy App
8
+
9
+ **initial setup**
10
+
11
+ ```shell
12
+ docker-compose build dummy
13
+ docker-compose run --rm dummy bash
14
+ ```
15
+
16
+ inside container:
5
17
 
6
18
  ```shell
7
19
  bundle install
8
20
  yarn install
9
- rake db:setup
10
- rails s
11
- ./bin/webpack --watch
21
+ cd spec/dummy
22
+ bundle install
23
+ npm install (npm and not yarn!)
24
+ rails app:db:setup
12
25
  ```
13
26
 
27
+ **dummy app start**
28
+
29
+ on your host:
14
30
  ```shell
15
- rails s
31
+ docker-compose up dummy
16
32
  ```
17
33
 
34
+ and
35
+
18
36
  ```shell
19
- ./bin/webpack --watch
37
+ docker-compose run --rm dummy sh -c "cd spec/dummy && ./bin/webpack --watch"
20
38
  ```
21
39
 
40
+ simultaneously to be able to visit the demo app on [localhost:3000](localhost:3000).
41
+
22
42
  ## Testing
23
43
 
44
+ **initial setup**
45
+
46
+ ```shell
47
+ docker-compose build dummy
48
+ docker-compose run --rm dummy bash
49
+ ```
50
+
51
+ inside container:
52
+
53
+ ```shell
54
+ bundle install
55
+ yarn install
56
+ cd spec/dummy
57
+ bundle install
58
+ npm install (npm and not yarn!)
59
+ rails app:db:setup
60
+ ```
61
+
62
+ **test run**
63
+
64
+ ```shell
65
+ docker-compose run --rm builder bash
66
+
67
+ ```
68
+
69
+ inside container:
70
+
71
+ ```shell
72
+ bundle exec rspec spec/test
73
+ ```
74
+
75
+ ## Release
76
+
24
77
  ```shell
25
- bundle exec rspec
78
+ docker-compose run --rm builder
79
+ gem bump ...
80
+ gem release
81
+ npm bump ...
82
+ npm release
83
+ git tag ...
26
84
  ```
@@ -2,17 +2,18 @@ class Matestack::Ui::Bootstrap::Components::Accordion < Matestack::Ui::Component
2
2
 
3
3
  # [ {header: { class, id, text, size, btn_variant, btn_class }, body: { class, text, multi } } ]
4
4
  optional :items # array with 2 Hashes: header and body
5
+ optional :open
6
+ optional :variant
5
7
  optional attributes: { as: :bs_attrs }, class: { as: :bs_class }, id: { as: :bs_id }
6
8
 
7
9
  def setup
8
10
  @accordion_id = (bs_id.present? ? bs_id : "matestack-accordion-#{SecureRandom.hex(3)}")
9
11
  end
12
+
10
13
  def response
11
14
  div accordion_attributes do
12
- div class: "card" do
13
- accordion_content_partial if items.present?
14
- yield_components
15
- end
15
+ accordion_content_partial if items.present?
16
+ yield_components
16
17
  end
17
18
  end
18
19
 
@@ -20,17 +21,17 @@ class Matestack::Ui::Bootstrap::Components::Accordion < Matestack::Ui::Component
20
21
 
21
22
  def accordion_content_partial
22
23
  items.each_with_index do | item, index |
23
- div class: "card-header p-0 #{item[:header][:class]}", id: (item[:header][:id] || "header-#{index}") do
24
- heading size: (item[:header][:size] || 2), class: "mb-0" do
25
- bs_btn variant: (item[:header][:variant] || :link), size: :block, class: (item[:header][:class] || "text-start"), text:item[:header][:text],
26
- data: { toggle: "collapse", target: "#collapse-#{(item[:header][:id] || "header-#{index}") }" },
27
- attributes: { "aria-expanded": "false", "aria-controls": "collapse-#{(item[:header][:id] || "header-#{index}")}" }
24
+ div class: "accordion-item" do
25
+ heading class: "accordion-header #{item[:header][:class]}", id: (item[:header][:id] || "header-#{index}"), size: (item[:header][:size] || 2) do
26
+ button class: "accordion-button", text:item[:header][:text],
27
+ data: { "bs-toggle": "collapse", "bs-target": "#collapse-#{(item[:header][:id] || "header-#{index}") }" },
28
+ attributes: { "aria-expanded": "false", "aria-controls": "collapse-#{(item[:header][:id] || "header-#{index}")}", type: "button" }
28
29
  end
29
- end
30
- bs_collapse id: "collapse-#{(item[:header][:id] || "header-#{index}")}", labelledby: (item[:header][:id] || "header-#{index}"),
31
- parent: @accordion_id, multi: (item[:body][:multi] || false) do
32
- div class: "card-body #{item[:body][:class]}" do
33
- plain item[:body][:text]
30
+ bs_collapse class: "accordion-collapse #{ 'show' if open || item[:open] }", id: "collapse-#{(item[:header][:id] || "header-#{index}")}", labelledby: (item[:header][:id] || "header-#{index}"),
31
+ parent: @accordion_id, multi: (item[:body][:multi] || false) do
32
+ div class: "accordion-body #{item[:body][:class]}" do
33
+ plain item[:body][:text]
34
+ end
34
35
  end
35
36
  end
36
37
  end
@@ -47,6 +48,8 @@ class Matestack::Ui::Bootstrap::Components::Accordion < Matestack::Ui::Component
47
48
  def accordion_classes
48
49
  [].tap do |classes|
49
50
  classes << 'accordion'
51
+ classes << 'open' if open
52
+ classes << 'accordion-flush' if variant == :flush
50
53
  classes << bs_class
51
54
  end.join(' ').strip
52
55
  end
@@ -7,7 +7,7 @@ class Matestack::Ui::Bootstrap::Components::Alert < Matestack::Ui::VueJsComponen
7
7
  def response
8
8
  div alert_attributes do
9
9
  heading size: (title_size || 4), class: 'alert-heading', text: title if title
10
- paragraph text: text if text
10
+ plain text if text
11
11
  yield_components
12
12
  bs_close dismiss: "alert" if dismissible
13
13
  end
@@ -1,14 +1,14 @@
1
1
  class Matestack::Ui::Bootstrap::Components::Badge < Matestack::Ui::Component
2
-
2
+
3
3
  optional class: { as: :bs_class }
4
- optional :text, :variant, :rounded, :sr_only
4
+ optional :text, :variant, :rounded, :visually_hidden
5
5
 
6
6
  def response
7
7
  span badge_attributes do
8
8
  plain text if text
9
9
  yield_components
10
10
  end
11
- span class: "sr-only", text: sr_only if sr_only.present?
11
+ span class: "visually-hidden", text: visually_hidden if visually_hidden.present?
12
12
  end
13
13
 
14
14
  protected
@@ -27,4 +27,4 @@ class Matestack::Ui::Bootstrap::Components::Badge < Matestack::Ui::Component
27
27
  classes << bs_class
28
28
  end.join(' ').strip
29
29
  end
30
- end
30
+ end
@@ -4,20 +4,22 @@ class Matestack::Ui::Bootstrap::Components::Breadcrumb < Matestack::Ui::Componen
4
4
  optional class: { as: :bs_class} # adding custom class to breadcrumb list
5
5
  optional :nav_class
6
6
 
7
- def response
7
+ def response
8
8
  nav class: nav_class, attributes: { 'aria-label': "breadcrumb" } do
9
- ol breadcrumb_attributes do
9
+ ol breadcrumb_attributes do
10
10
  items&.each_with_index do |item, index|
11
11
  li link_attrs((items.size - 1) == index) do
12
12
  case item[:type]
13
13
  when :link
14
- link path: item[:path], text: item[:text]
14
+ link item
15
+ when :transition
16
+ transition item
15
17
  else
16
- transition path: item[:path], text: item[:text]
18
+ plain item[:text]
17
19
  end
18
20
  end
19
21
  end
20
- yield_components
22
+ yield_components
21
23
  end
22
24
  end
23
25
  end
@@ -43,4 +45,4 @@ class Matestack::Ui::Bootstrap::Components::Breadcrumb < Matestack::Ui::Componen
43
45
  classes << bs_class
44
46
  end.join(' ').strip
45
47
  end
46
- end
48
+ end
@@ -2,11 +2,26 @@ class Matestack::Ui::Bootstrap::Components::Button < Matestack::Ui::Component
2
2
 
3
3
  optional :text, :type, :variant, :size, :outline
4
4
  optional attributes: { as: :bs_attrs }, class: { as: :bs_class }
5
- optional :is_transition
5
+ optional transition: { as: :bs_btn_transition }
6
+ optional action: { as: :bs_btn_action }
7
+ optional onclick: { as: :bs_btn_onclick }
8
+ optional link: { as: :bs_btn_link }
6
9
 
7
10
  def response
8
- if is_transition
9
- transition button_attributes.merge({path: root_path}) do
11
+ if bs_btn_transition.present? && bs_btn_transition.is_a?(Hash)
12
+ transition button_attributes.merge(bs_btn_transition.merge({attributes: { role: "button"} })) do
13
+ inner_response
14
+ end
15
+ elsif bs_btn_action.present? && bs_btn_action.is_a?(Hash)
16
+ action button_attributes.merge(bs_btn_action.merge({attributes: { role: "button"} })) do
17
+ inner_response
18
+ end
19
+ elsif bs_btn_onclick.present? && bs_btn_onclick.is_a?(Hash)
20
+ onclick button_attributes.merge(bs_btn_onclick.merge({attributes: { role: "button"} })) do
21
+ inner_response
22
+ end
23
+ elsif bs_btn_link.present? && bs_btn_link.is_a?(Hash)
24
+ link button_attributes.merge(bs_btn_link.merge({attributes: { role: "button"} })) do
10
25
  inner_response
11
26
  end
12
27
  else
@@ -1,7 +1,7 @@
1
1
  class Matestack::Ui::Bootstrap::Components::Carousel < Matestack::Ui::VueJsComponent
2
- vue_js_component_name "matestack-ui-bootstrap-carousel"
3
-
4
- optional :start, :controls, :indicators, :fade, :interval
2
+ vue_js_component_name "matestack-ui-bootstrap-carousel"
3
+
4
+ optional :start, :controls, :indicators, :fade, :interval, :variant
5
5
  optional :items, class: { as: :bs_class }
6
6
  # possible keys for items: path, title, text, interval
7
7
  # event trigger
@@ -10,7 +10,7 @@ class Matestack::Ui::Bootstrap::Components::Carousel < Matestack::Ui::VueJsCompo
10
10
  def setup
11
11
  @component_config["carousel-id"] = carousel_id
12
12
  end
13
-
13
+
14
14
  def response
15
15
  div carousel_attributes do
16
16
  # carousel indicator
@@ -29,7 +29,7 @@ class Matestack::Ui::Bootstrap::Components::Carousel < Matestack::Ui::VueJsCompo
29
29
  def indicator_partial
30
30
  ol class: "carousel-indicators" do
31
31
  items.size.times do |index|
32
- li data: { target: carousel_id, 'slide-to': index },
32
+ li data: { "bs-target": "##{carousel_id}", 'bs-slide-to': index },
33
33
  class: "#{'active' if index == (start || 0) }"
34
34
  end
35
35
  end
@@ -37,8 +37,8 @@ class Matestack::Ui::Bootstrap::Components::Carousel < Matestack::Ui::VueJsCompo
37
37
 
38
38
  def carousel_partial
39
39
  items.each_with_index do |item, index|
40
- div class: "carousel-item #{'active' if index == (start || 0) } #{item[:class]}".strip,
41
- data: { interval: item[:interval] } do
40
+ div class: "carousel-item #{'active' if index == (start || 0) } #{item[:class]}".strip,
41
+ data: { "bs-interval": item[:interval] } do
42
42
  img class: "d-block w-100", path: item[:path]
43
43
  if item[:title] || item[:text]
44
44
  div class: "carousel-caption d-none d-md-block #{item[:title_class]}" do
@@ -51,13 +51,13 @@ class Matestack::Ui::Bootstrap::Components::Carousel < Matestack::Ui::VueJsCompo
51
51
  end
52
52
 
53
53
  def controls_partial
54
- link class: "carousel-control-prev", path: "##{carousel_id}", data: { slide: :prev }, attributes: { 'role': "button" } do
54
+ link class: "carousel-control-prev", data: { "bs-target": "##{carousel_id}", "bs-slide": :prev }, attributes: { 'role': "button" } do
55
55
  span class: "carousel-control-prev-icon", attributes: { 'aria-hidden': "true" }
56
- span class: "sr-only", text: "Previous"
56
+ span class: "visually-hidden", text: "Previous"
57
57
  end
58
- link class: "carousel-control-next", path: "##{carousel_id}", data: { slide: :next }, attributes: { 'role': "button" } do
58
+ link class: "carousel-control-next", data: { "bs-target": "##{carousel_id}", "bs-slide": :next }, attributes: { 'role': "button" } do
59
59
  span class: "carousel-control-next-icon", attributes: { 'aria-hidden': "true" }
60
- span class: "sr-only", text: "Next"
60
+ span class: "visually-hidden", text: "Next"
61
61
  end
62
62
  end
63
63
 
@@ -65,7 +65,7 @@ class Matestack::Ui::Bootstrap::Components::Carousel < Matestack::Ui::VueJsCompo
65
65
  html_attributes.merge(
66
66
  id: carousel_id,
67
67
  class: carousel_classes,
68
- data: { ride: 'carousel', interval: (interval || 5000) }
68
+ data: { "bs-ride": 'carousel', "bs-interval": (interval || 5000) }
69
69
  )
70
70
  end
71
71
 
@@ -73,7 +73,8 @@ class Matestack::Ui::Bootstrap::Components::Carousel < Matestack::Ui::VueJsCompo
73
73
  [].tap do |classes|
74
74
  classes << 'carousel slide'
75
75
  classes << 'carousel-fade' if fade
76
- #custom classes
76
+ classes << 'carousel-dark' if variant == :dark
77
+ #custom classes
77
78
  classes << bs_class
78
79
  end.join(' ').strip
79
80
  end
@@ -82,4 +83,4 @@ class Matestack::Ui::Bootstrap::Components::Carousel < Matestack::Ui::VueJsCompo
82
83
  @carousel_id ||= "matestack-carousel-#{SecureRandom.hex}"
83
84
  end
84
85
 
85
- end
86
+ end
@@ -14,7 +14,7 @@ class Matestack::Ui::Bootstrap::Components::Close < Matestack::Ui::Component
14
14
  def close_attributes
15
15
  html_attributes.merge(
16
16
  class: close_classes,
17
- data: { dismiss: "#{dismiss}" },
17
+ data: { "bs-dismiss": "#{dismiss}" },
18
18
  type: 'button',
19
19
  attributes: (attributes || {}).merge({ 'aria-label': 'Close' })
20
20
  )
@@ -1,12 +1,12 @@
1
1
  class Matestack::Ui::Bootstrap::Components::Collapse < Matestack::Ui::VueJsComponent
2
- vue_js_component_name "matestack-ui-bootstrap-collapse"
3
-
2
+ vue_js_component_name "matestack-ui-bootstrap-collapse"
3
+
4
4
  optional :multi, :labelledby, :parent, class: { as: :bs_class }
5
5
  optional :card # possible keys: class, text
6
6
  # event trigger
7
7
  optional :toggle_on, :show_on, :hide_on, :dispose_on
8
8
 
9
- def response
9
+ def response
10
10
  div collapse_attributes do
11
11
  card_partial if card
12
12
  yield_components
@@ -25,7 +25,7 @@ class Matestack::Ui::Bootstrap::Components::Collapse < Matestack::Ui::VueJsCompo
25
25
  def collapse_attributes
26
26
  html_attributes.merge(
27
27
  class: collapse_classes,
28
- data: { parent: parent },
28
+ data: { "bs-parent": parent },
29
29
  attributes: { 'aria-labelledby': "#{labelledby}" }
30
30
  )
31
31
  end
@@ -35,9 +35,9 @@ class Matestack::Ui::Bootstrap::Components::Collapse < Matestack::Ui::VueJsCompo
35
35
  classes << 'collapse'
36
36
  # mulit target
37
37
  classes << 'multi-collapse' if multi
38
- #custom classes
38
+ #custom classes
39
39
  classes << bs_class
40
40
  end.join(' ').strip
41
41
  end
42
42
 
43
- end
43
+ end
@@ -30,7 +30,7 @@ class Matestack::Ui::Bootstrap::Components::Dropdown < Matestack::Ui::VueJsCompo
30
30
  def split_btn_partial
31
31
  slot slots[:split_btn]
32
32
  bs_btn btn_attributes do
33
- span class:"sr-only" do plain "Toggle Dropdown" end
33
+ span class:"visually-hidden" do plain "Toggle Dropdown" end
34
34
  end
35
35
  end
36
36
 
@@ -47,6 +47,8 @@ class Matestack::Ui::Bootstrap::Components::Dropdown < Matestack::Ui::VueJsCompo
47
47
  li do transition item.merge(class: "dropdown-item #{item[:class]}") end
48
48
  when :action
49
49
  li do action item.merge(class: "dropdown-item #{item[:class]}") do plain item[:text] end end
50
+ when :onclick
51
+ li do onclick item.merge(class: "dropdown-item #{item[:class]}", attributes: { style: "cursor: pointer;" }) do plain item[:text] end end
50
52
  else
51
53
  span class: "dropdown-item-text" do plain item[:text] end
52
54
  end
@@ -99,7 +101,6 @@ class Matestack::Ui::Bootstrap::Components::Dropdown < Matestack::Ui::VueJsCompo
99
101
  def menu_attributes
100
102
  {
101
103
  class: menu_classes,
102
- data: { toggle: 'dropdown' },
103
104
  attributes: { 'aria-labelledby': bs_id }
104
105
  }
105
106
  end
@@ -1,50 +1,87 @@
1
1
  class Matestack::Ui::Bootstrap::Components::ListGroup < Matestack::Ui::Component
2
2
  html_attributes :role
3
3
 
4
- # optional :id
5
- optional :items
4
+ optional :items
6
5
  optional :horizontal, :horizontal_size, :checkbox
7
- optional :flush, :tablist, class: { as: :bs_class }
6
+ optional :variant, class: { as: :bs_class }
8
7
 
9
8
 
10
- def response
11
- ul list_group_attributes do
12
- yield_components unless items
13
- list_partial if items
9
+ def response
10
+ if actionable_items?
11
+ div list_group_attributes do
12
+ yield_components unless items
13
+ list_partial if items
14
+ end
15
+ else
16
+ ul list_group_attributes do
17
+ yield_components unless items
18
+ list_partial if items
19
+ end
14
20
  end
15
21
  end
16
22
 
17
23
  protected
18
24
 
25
+ def actionable_items?
26
+ if items.present?
27
+ items.any? { |item| [:tab, :transition, :action, :link].include?(item[:type]) }
28
+ else
29
+ false
30
+ end
31
+ end
32
+
33
+ def tab_nav?
34
+ if items.present?
35
+ items.any? { |item| item[:type] == :tab }
36
+ else
37
+ false
38
+ end
39
+ end
40
+
19
41
  def list_partial
20
42
  items.each do |item|
21
- case item[:type]
22
- when :link
43
+ case item[:type]
44
+ when :link
23
45
  link link_attrs(item) do
24
- plain item[:text]
46
+ text_rendering(item)
47
+ end
48
+ when :tab
49
+ link tab_attrs(item) do
50
+ text_rendering(item)
25
51
  end
26
- when :transition
27
- transition link_attrs(item) do
28
- plain item[:text]
52
+ when :transition
53
+ transition transition_attrs(item) do
54
+ text_rendering(item)
29
55
  end
30
- when :label
56
+ when :action
57
+ action action_attrs(item) do
58
+ text_rendering(item)
59
+ end
60
+ when :label
31
61
  label id: item[:id], class: "#{list_classes item, false}" do
32
62
  input class: "form-check-input me-1", attributes: { 'type': "checkbox", 'value': "" } if checkbox
33
- plain item[:text]
63
+ text_rendering(item)
34
64
  end
35
65
  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]
66
+ li id: item[:id], class: "#{list_classes item, false}", attributes: { "aria-disabled": "#{true if item[:disabled]}" } do
67
+ # this implementation is useless, would need to be connected to a form through bs_form_checkbox
68
+ # input class: "form-check-input me-1", attributes: { 'type': "checkbox", 'value': "", 'aria-label': "#{item[:text]}" } if checkbox
69
+ text_rendering(item)
70
+ bs_badge variant: :primary, rounded: true, text: item[:badge] if item[:badge]
39
71
  end
40
72
  end
41
73
  end
42
74
  end
43
75
 
76
+ def text_rendering(item)
77
+ bs_icon name: item[:icon] if item[:icon]
78
+ plain item[:text]
79
+ end
80
+
44
81
  def list_group_attributes
45
82
  attributes = {}.tap do |hash|
46
83
  hash[:class] = list_group_classes
47
- hash[:attributes] = { role: "tablist" } if tablist
84
+ hash[:attributes] = { role: "tablist" } if tab_nav?
48
85
  end
49
86
  html_attributes.merge(
50
87
  attributes
@@ -55,29 +92,54 @@ class Matestack::Ui::Bootstrap::Components::ListGroup < Matestack::Ui::Component
55
92
  [].tap do |classes|
56
93
  classes << 'list-group'
57
94
  classes << (horizontal_size.present? ? "list-group-horizontal-#{horizontal_size}": "list-group-horizontal") if horizontal
58
- classes << 'list-group-flush' if flush
95
+ classes << 'list-group-flush' if variant == :flush
59
96
  classes << bs_class
60
97
  end.join(' ').strip
61
98
  end
62
99
 
63
100
  def link_attrs(item)
101
+ attrs = item
102
+ attrs[:class] = "#{list_classes item, true}"
103
+ attrs[:attributes] = { "aria-disabled": "#{true if item[:disabled]}" } if item[:disabled]
104
+ attrs
105
+ end
106
+
107
+ def tab_attrs(item)
64
108
  {}.tap do |hash|
65
- hash[:id] = item[:id]
109
+ hash[:id] = "tab-#{item[:id]}" if tab_nav?
66
110
  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]
111
+ hash[:data] = { "bs-toggle": "list" }
112
+ hash[:attributes] = { "aria-disabled": "#{true if item[:disabled]}" } if item[:disabled]
113
+ hash[:attributes] = { 'aria-controls': "#tab-#{item[:id]}-content", role: "tab" }
114
+ hash[:path] = "#tab-#{item[:id]}-content"
115
+ hash[:target] = item[:target]
70
116
  end
71
117
  end
72
118
 
119
+ def transition_attrs(item)
120
+ attrs = item
121
+ attrs[:class] = "#{list_classes item, true}"
122
+ attrs[:attributes] = { "aria-disabled": "#{true if item[:disabled]}" } if item[:disabled]
123
+ attrs
124
+ end
125
+
126
+ def action_attrs(item)
127
+ attrs = item
128
+ attrs[:class] = "#{list_classes item, true}"
129
+ attrs[:attributes] = { "aria-disabled": "#{true if item[:disabled]}" } if item[:disabled]
130
+ attrs
131
+ end
132
+
73
133
  def list_classes(item, action)
74
134
  [].tap do |classes|
75
135
  classes << 'list-group-item'
76
136
  classes << 'list-group-item-action' if action
77
137
  classes << "list-group-item-#{item[:variant]}" if item[:variant].present?
78
138
  classes << 'active' if item[:active]
139
+ classes << 'disabled' if item[:disabled]
140
+ classes << 'd-flex justify-content-between align-items-center' if item[:badge].present?
79
141
  classes << item[:class]
80
142
  end.join(' ').strip
81
143
  end
82
144
 
83
- end
145
+ end