blacklight 8.8.0 → 9.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (178) hide show
  1. checksums.yaml +4 -4
  2. data/.env +3 -3
  3. data/.github/pull_request_template.md +7 -0
  4. data/.github/workflows/ruby.yml +16 -19
  5. data/.rubocop.yml +2 -2
  6. data/.rubocop_todo.yml +0 -9
  7. data/README.md +30 -8
  8. data/VERSION +1 -1
  9. data/app/assets/builds/blacklight.css +448 -0
  10. data/app/assets/javascripts/blacklight/blacklight.esm.js +19 -16
  11. data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
  12. data/app/assets/javascripts/blacklight/blacklight.js +19 -16
  13. data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
  14. data/app/assets/stylesheets/blacklight/_balanced_list.scss +1 -4
  15. data/app/assets/stylesheets/blacklight/_blacklight_base.scss +1 -3
  16. data/app/assets/stylesheets/blacklight/_bookmark.scss +44 -41
  17. data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +7 -26
  18. data/app/assets/stylesheets/blacklight/_constraints.scss +15 -24
  19. data/app/assets/stylesheets/blacklight/_controls.scss +2 -18
  20. data/app/assets/stylesheets/blacklight/_facets.scss +15 -82
  21. data/app/assets/stylesheets/blacklight/_group.scss +2 -5
  22. data/app/assets/stylesheets/blacklight/_header.scss +4 -11
  23. data/app/assets/stylesheets/blacklight/_icons.scss +0 -8
  24. data/app/assets/stylesheets/blacklight/_modal.scss +2 -2
  25. data/app/assets/stylesheets/blacklight/_pagination.scss +0 -4
  26. data/app/assets/stylesheets/blacklight/_search_form.scss +7 -1
  27. data/app/assets/stylesheets/blacklight/_search_history.scss +0 -4
  28. data/app/assets/stylesheets/blacklight/_search_results.scss +1 -15
  29. data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +9 -14
  30. data/app/assets/stylesheets/blacklight/build.scss +4 -0
  31. data/app/components/blacklight/advanced_search_form_component.rb +1 -1
  32. data/app/components/blacklight/constraint_component.rb +1 -1
  33. data/app/components/blacklight/constraint_layout_component.html.erb +2 -2
  34. data/app/components/blacklight/constraints_component.html.erb +2 -2
  35. data/app/components/blacklight/constraints_component.rb +1 -1
  36. data/app/components/blacklight/document/bookmark_component.html.erb +3 -3
  37. data/app/components/blacklight/document/group_component.html.erb +1 -1
  38. data/app/components/blacklight/document/page_header_component.rb +1 -1
  39. data/app/components/blacklight/document/sidebar_component.rb +5 -5
  40. data/app/components/blacklight/document_component.rb +9 -13
  41. data/app/components/blacklight/document_title_component.rb +3 -2
  42. data/app/components/blacklight/facet_field_component.html.erb +4 -4
  43. data/app/components/blacklight/facet_field_list_component.rb +4 -22
  44. data/app/components/blacklight/facet_field_pagination_component.html.erb +4 -4
  45. data/app/components/blacklight/facet_field_pagination_component.rb +2 -1
  46. data/app/components/blacklight/facet_item_component.rb +2 -2
  47. data/app/components/blacklight/facet_item_pivot_component.rb +2 -2
  48. data/app/components/blacklight/response/facet_group_component.html.erb +3 -18
  49. data/app/components/blacklight/response/facet_group_component.rb +7 -23
  50. data/app/components/blacklight/response/facet_toggle_button_component.html.erb +16 -0
  51. data/app/components/blacklight/response/facet_toggle_button_component.rb +14 -0
  52. data/app/components/blacklight/response/pagination_component.html.erb +1 -1
  53. data/app/components/blacklight/response/pagination_component.rb +2 -1
  54. data/app/components/blacklight/response/sort_component.rb +1 -0
  55. data/app/components/blacklight/response/view_type_button_component.html.erb +1 -1
  56. data/app/components/blacklight/response/view_type_component.html.erb +1 -1
  57. data/app/components/blacklight/search/facet_suggest_input.html.erb +7 -7
  58. data/app/components/blacklight/search/facet_suggest_input.rb +0 -4
  59. data/app/components/blacklight/search/per_page_component.html.erb +1 -1
  60. data/app/components/blacklight/search/per_page_component.rb +1 -0
  61. data/app/components/blacklight/search/sidebar_component.html.erb +1 -1
  62. data/app/components/blacklight/search/sidebar_component.rb +1 -1
  63. data/app/components/blacklight/search_bar_component.html.erb +3 -3
  64. data/app/components/blacklight/search_bar_component.rb +2 -2
  65. data/app/components/blacklight/search_button_component.rb +2 -2
  66. data/app/components/blacklight/search_context/server_applied_params_component.html.erb +2 -2
  67. data/app/components/blacklight/search_context/server_applied_params_component.rb +9 -0
  68. data/app/components/blacklight/skip_link_component.html.erb +1 -1
  69. data/app/components/blacklight/skip_link_component.rb +7 -3
  70. data/app/components/blacklight/skip_link_item_component.rb +18 -0
  71. data/app/components/blacklight/top_navbar_component.html.erb +1 -1
  72. data/app/controllers/concerns/blacklight/catalog.rb +3 -2
  73. data/app/controllers/concerns/blacklight/search_context.rb +0 -12
  74. data/app/helpers/blacklight/blacklight_helper_behavior.rb +0 -6
  75. data/app/helpers/blacklight/catalog_helper_behavior.rb +6 -12
  76. data/app/helpers/blacklight/configuration_helper_behavior.rb +0 -12
  77. data/app/helpers/blacklight/document_helper_behavior.rb +0 -26
  78. data/app/helpers/blacklight/icon_helper_behavior.rb +1 -9
  79. data/app/helpers/blacklight/layout_helper_behavior.rb +2 -2
  80. data/app/helpers/blacklight/render_partials_helper_behavior.rb +0 -14
  81. data/app/helpers/blacklight/url_helper_behavior.rb +1 -1
  82. data/app/javascript/{blacklight → blacklight-frontend}/bookmark_toggle.js +1 -1
  83. data/app/javascript/{blacklight → blacklight-frontend}/core.js +2 -10
  84. data/app/javascript/{blacklight → blacklight-frontend}/debounce.js +1 -1
  85. data/app/javascript/{blacklight → blacklight-frontend}/facet_suggest.js +4 -4
  86. data/app/javascript/blacklight-frontend/index.js +18 -0
  87. data/app/javascript/{blacklight → blacklight-frontend}/modal.js +16 -2
  88. data/app/models/blacklight/facet_paginator.rb +1 -1
  89. data/app/models/concerns/blacklight/document.rb +0 -11
  90. data/app/models/concerns/blacklight/user.rb +1 -1
  91. data/app/presenters/blacklight/facet_field_presenter.rb +2 -2
  92. data/app/services/blacklight/search_params_yaml_coder.rb +0 -2
  93. data/app/views/bookmarks/_clear_bookmarks_widget.html.erb +0 -2
  94. data/app/views/bookmarks/index.html.erb +1 -1
  95. data/app/views/catalog/_results_pagination.html.erb +2 -5
  96. data/app/views/catalog/_search_results.html.erb +4 -4
  97. data/app/views/catalog/_search_results_header.html.erb +1 -1
  98. data/app/views/catalog/_sort_and_per_page.html.erb +1 -1
  99. data/app/views/catalog/_sort_widget.html.erb +1 -0
  100. data/app/views/catalog/facet.html.erb +1 -1
  101. data/app/views/catalog/show.html.erb +2 -3
  102. data/app/views/kaminari/blacklight/_paginator.html.erb +1 -2
  103. data/app/views/layouts/blacklight/base.html.erb +3 -7
  104. data/app/views/search_history/index.html.erb +0 -2
  105. data/blacklight.gemspec +4 -4
  106. data/compose.yaml +1 -0
  107. data/config/importmap.rb +1 -1
  108. data/config/locales/blacklight.ar.yml +4 -4
  109. data/config/locales/blacklight.ca.yml +124 -124
  110. data/config/locales/blacklight.de.yml +2 -2
  111. data/config/locales/blacklight.en.yml +14 -14
  112. data/config/locales/blacklight.es.yml +4 -4
  113. data/config/locales/blacklight.fr.yml +4 -4
  114. data/config/locales/blacklight.hu.yml +4 -4
  115. data/config/locales/blacklight.it.yml +3 -3
  116. data/config/locales/blacklight.nl.yml +3 -3
  117. data/config/locales/blacklight.pt-BR.yml +3 -3
  118. data/config/locales/blacklight.sq.yml +4 -4
  119. data/config/locales/blacklight.zh.yml +4 -4
  120. data/lib/blacklight/configuration/display_field.rb +1 -1
  121. data/lib/blacklight/configuration/fields.rb +3 -3
  122. data/lib/blacklight/configuration/view_config.rb +0 -2
  123. data/lib/blacklight/configuration.rb +7 -12
  124. data/lib/blacklight/engine.rb +0 -6
  125. data/lib/blacklight/open_struct_with_hash_access.rb +4 -4
  126. data/lib/blacklight/search_builder.rb +4 -4
  127. data/lib/blacklight/solr/request.rb +1 -7
  128. data/lib/blacklight/solr/response/group_response.rb +2 -2
  129. data/lib/blacklight.rb +1 -1
  130. data/lib/generators/blacklight/assets/importmap_generator.rb +8 -24
  131. data/lib/generators/blacklight/assets/propshaft_generator.rb +1 -1
  132. data/lib/generators/blacklight/assets_generator.rb +3 -3
  133. data/lib/generators/blacklight/controller_generator.rb +3 -3
  134. data/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +1 -1
  135. data/lib/generators/blacklight/user_generator.rb +9 -10
  136. data/package.json +14 -4
  137. data/rollup.config.js +1 -1
  138. data/spec/components/blacklight/document/action_component_spec.rb +1 -5
  139. data/spec/components/blacklight/document/sidebar_component_spec.rb +5 -20
  140. data/spec/components/blacklight/facet_field_checkboxes_component_spec.rb +2 -2
  141. data/spec/components/blacklight/facet_field_list_component_spec.rb +2 -2
  142. data/spec/components/blacklight/search/facet_suggest_input_spec.rb +2 -18
  143. data/spec/components/blacklight/search_bar_component_spec.rb +1 -1
  144. data/spec/features/axe_spec.rb +6 -11
  145. data/spec/features/bookmarks_spec.rb +48 -11
  146. data/spec/features/facets_spec.rb +25 -14
  147. data/spec/features/search_context_spec.rb +1 -2
  148. data/spec/features/search_filters_spec.rb +6 -6
  149. data/spec/helpers/blacklight/configuration_helper_behavior_spec.rb +0 -9
  150. data/spec/helpers/blacklight/render_partials_helper_behavior_spec.rb +1 -1
  151. data/spec/helpers/catalog_helper_spec.rb +8 -0
  152. data/spec/models/blacklight/solr/request_spec.rb +7 -0
  153. data/spec/test_app_templates/Gemfile.extra +0 -1
  154. data/spec/views/catalog/_facet_layout.html.erb_spec.rb +3 -3
  155. data/spec/views/catalog/index.html.erb_spec.rb +6 -3
  156. data/spec/views/catalog/show.html.erb_spec.rb +1 -0
  157. data/tasks/blacklight.rake +8 -5
  158. metadata +30 -57
  159. data/app/assets/stylesheets/blacklight/_autocomplete.scss +0 -25
  160. data/app/assets/stylesheets/blacklight/_mixins.scss +0 -20
  161. data/app/components/blacklight/icons/legacy_icon_component.rb +0 -30
  162. data/app/javascript/blacklight/index.js +0 -18
  163. data/app/views/catalog/_constraints.html.erb +0 -1
  164. data/app/views/catalog/_facets.html.erb +0 -5
  165. data/app/views/catalog/_search_form.html.erb +0 -7
  166. data/app/views/catalog/_search_header.html.erb +0 -1
  167. data/app/views/catalog/_show_sidebar.html.erb +0 -3
  168. data/app/views/catalog/_show_tools.html.erb +0 -2
  169. data/app/views/catalog/_start_over.html.erb +0 -1
  170. data/app/views/shared/_header_navbar.html.erb +0 -1
  171. data/lib/generators/blacklight/assets/sprockets_generator.rb +0 -68
  172. data/spec/views/catalog/_search_header.erb_spec.rb +0 -14
  173. data/spec/views/catalog/_show_sidebar.erb_spec.rb +0 -24
  174. data/spec/views/catalog/_show_tools.html.erb_spec.rb +0 -37
  175. /data/app/javascript/{blacklight → blacklight-frontend}/button_focus.js +0 -0
  176. /data/app/javascript/{blacklight → blacklight-frontend}/checkbox_submit.js +0 -0
  177. /data/app/javascript/{blacklight → blacklight-frontend}/modalForm.js +0 -0
  178. /data/app/javascript/{blacklight → blacklight-frontend}/search_context.js +0 -0
@@ -16,12 +16,12 @@ module Blacklight
16
16
 
17
17
  private
18
18
 
19
- def render_show_tools
20
- blacklight_config.view_config(:show).show_tools_component&.tap do |show_tools_component_class|
21
- return render show_tools_component_class.new(document: document)
22
- end
19
+ def show_tools_component_class
20
+ blacklight_config.view_config(:show).show_tools_component
21
+ end
23
22
 
24
- render 'show_tools', document: document, silence_deprecation: helpers.partial_from_blacklight?('show_tools')
23
+ def render_show_tools
24
+ render show_tools_component_class.new(document: document)
25
25
  end
26
26
  end
27
27
  end
@@ -22,9 +22,6 @@ module Blacklight
22
22
  class DocumentComponent < Blacklight::Component
23
23
  with_collection_parameter :document
24
24
 
25
- # ViewComponent 3 changes iteration counters to begin at 0 rather than 1
26
- COLLECTION_INDEX_OFFSET = ViewComponent::VERSION::MAJOR < 3 ? 0 : 1
27
-
28
25
  # Content appearing before the document
29
26
  renders_one :header
30
27
 
@@ -37,7 +34,7 @@ module Blacklight
37
34
 
38
35
  # The document title with some reasonable default behavior
39
36
  renders_one :title, (lambda do |*args, component: nil, **kwargs|
40
- component ||= @presenter&.view_config&.title_component || Blacklight::DocumentTitleComponent
37
+ component ||= view_config.title_component || Blacklight::DocumentTitleComponent
41
38
 
42
39
  component.new(*args, counter: @counter, document: @document, presenter: @presenter, as: @title_component, actions: !@show, link_to_document: !@show, document_component: self, **kwargs)
43
40
  end)
@@ -45,7 +42,7 @@ module Blacklight
45
42
  renders_one :embed, (lambda do |static_content = nil, *args, component: nil, **kwargs|
46
43
  next static_content if static_content.present?
47
44
 
48
- component ||= @presenter.view_config&.embed_component
45
+ component ||= view_config.embed_component
49
46
 
50
47
  next unless component
51
48
 
@@ -56,7 +53,7 @@ module Blacklight
56
53
  renders_one :metadata, (lambda do |static_content = nil, *args, component: nil, fields: nil, **kwargs|
57
54
  next static_content if static_content.present?
58
55
 
59
- component ||= @presenter&.view_config&.metadata_component || Blacklight::DocumentMetadataComponent
56
+ component ||= view_config.metadata_component || Blacklight::DocumentMetadataComponent
60
57
 
61
58
  component.new(*args, fields: fields || @presenter&.field_presenters || [], **kwargs)
62
59
  end)
@@ -67,7 +64,7 @@ module Blacklight
67
64
  renders_one :thumbnail, (lambda do |image_options_or_static_content = {}, *args, component: nil, **kwargs|
68
65
  next image_options_or_static_content if image_options_or_static_content.is_a? String
69
66
 
70
- component ||= @presenter&.view_config&.thumbnail_component || Blacklight::Document::ThumbnailComponent
67
+ component ||= view_config.thumbnail_component || Blacklight::Document::ThumbnailComponent
71
68
 
72
69
  component.new(*args, document: @document, presenter: @presenter, counter: @counter, image_options: image_options_or_static_content, **kwargs)
73
70
  end)
@@ -81,7 +78,6 @@ module Blacklight
81
78
 
82
79
  # rubocop:disable Metrics/ParameterLists
83
80
  # @param document [Blacklight::DocumentPresenter]
84
- # @param presenter [Blacklight::DocumentPresenter] alias for document
85
81
  # @param partials [Array, nil] view partial names that should be used to provide content for the `partials` slot
86
82
  # @param id [String] HTML id for the root element
87
83
  # @param classes [Array, String] additional HTML classes for the root element
@@ -91,13 +87,11 @@ module Blacklight
91
87
  # @param document_counter [Number, nil] provided by ViewComponent collection iteration
92
88
  # @param counter_offset [Number] the offset of the start of the collection counter parameter for the component to the overall result set
93
89
  # @param show [Boolean] are we showing only a single document (vs a list of search results); used for backwards-compatibility
94
- def initialize(document: nil, presenter: nil, partials: nil,
90
+ def initialize(document: nil, partials: nil,
95
91
  id: nil, classes: [], component: :article, title_component: nil,
96
92
  counter: nil, document_counter: nil, counter_offset: 0,
97
93
  show: false, **args)
98
- Blacklight.deprecation.warn('the `presenter` argument to DocumentComponent#initialize is deprecated; pass the `presenter` in as document instead') if presenter
99
-
100
- @presenter = presenter || document || args[self.class.collection_parameter]
94
+ @presenter = document || args[self.class.collection_parameter]
101
95
  @document = @presenter.document
102
96
  @view_partials = partials || []
103
97
 
@@ -108,7 +102,7 @@ module Blacklight
108
102
 
109
103
  @counter = counter
110
104
  @document_counter = document_counter || args.fetch(self.class.collection_counter_parameter, nil)
111
- @counter ||= @document_counter + COLLECTION_INDEX_OFFSET + counter_offset if @document_counter.present?
105
+ @counter ||= 1 + @document_counter + counter_offset if @document_counter.present?
112
106
 
113
107
  @show = show
114
108
  end
@@ -139,6 +133,8 @@ module Blacklight
139
133
 
140
134
  private
141
135
 
136
+ delegate :view_config, to: :@presenter
137
+
142
138
  attr_reader :document_counter, :presenter, :view_partials
143
139
 
144
140
  def show?
@@ -7,7 +7,8 @@ module Blacklight
7
7
  renders_many :actions
8
8
 
9
9
  # rubocop:disable Metrics/ParameterLists
10
- def initialize(title = nil, document: nil, presenter: nil, as: :h3, counter: nil, classes: 'index_title document-title-heading col', link_to_document: true, document_component: nil, actions: true)
10
+ def initialize(title = nil, document: nil, presenter: nil, as: :h3, counter: nil, classes: 'index_title document-title-heading col h5', link_to_document: true, document_component: nil,
11
+ actions: true)
11
12
  raise ArgumentError, 'missing keyword: :document or :presenter' if presenter.nil? && document.nil?
12
13
 
13
14
  @title = title
@@ -42,7 +43,7 @@ module Blacklight
42
43
 
43
44
  (@has_actions_slot && get_slot(:actions)) ||
44
45
  ([@document_component&.actions] if @document_component&.actions.present?) ||
45
- [helpers.render_index_doc_actions(presenter.document, wrapping_class: 'index-document-functions col-sm-3 col-lg-2')]
46
+ [helpers.render_index_doc_actions(presenter.document, wrapping_class: 'index-document-functions col-sm-3 col-lg-2 mb-4 mb-sm-0')]
46
47
  end
47
48
 
48
49
  def counter
@@ -1,8 +1,8 @@
1
- <div class="card facet-limit blacklight-<%= @facet_field.key %> <%= 'facet-limit-active' if @facet_field.active? %>">
2
- <h3 class="card-header p-0 facet-field-heading" id="<%= header_html_id %>">
1
+ <div class="accordion-item facet-limit blacklight-<%= @facet_field.key %> <%= 'facet-limit-active' if @facet_field.active? %>">
2
+ <h3 class="accordion-header p-0 facet-field-heading h6" id="<%= header_html_id %>">
3
3
  <button
4
4
  type="button"
5
- class="btn w-100 d-block btn-block p-2 text-start text-left collapse-toggle <%= "collapsed" if @facet_field.collapsed? %>"
5
+ class="btn accordion-button <%= "collapsed" if @facet_field.collapsed? %>"
6
6
  data-toggle="collapse"
7
7
  data-bs-toggle="collapse"
8
8
  data-target="#<%= html_id %>"
@@ -14,7 +14,7 @@
14
14
  </button>
15
15
  </h3>
16
16
  <div id="<%= html_id %>" role="region" aria-labelledby="<%= header_html_id %>" class="panel-collapse facet-content collapse <%= "show" unless @facet_field.collapsed? %>">
17
- <div class="card-body">
17
+ <div class="accordion-body">
18
18
  <%= body %>
19
19
 
20
20
  <% if @facet_field.modal_path %>
@@ -7,24 +7,6 @@ module Blacklight
7
7
  @layout = layout == false ? FacetFieldNoLayoutComponent : Blacklight::FacetFieldComponent
8
8
  end
9
9
 
10
- ##
11
- # Renders the list of values
12
- # removes any elements where render_facet_item returns a nil value. This enables an application
13
- # to filter undesireable facet items so they don't appear in the UI
14
- # @deprecated
15
- def render_facet_limit_list(paginator, facet_field, wrapping_element = :li)
16
- return render(facet_items(wrapping_element: wrapping_element)) if paginator == @facet_field.paginator && facet_field == @facet_field.key
17
-
18
- facet_config ||= helpers.facet_configuration_for_field(facet_field)
19
-
20
- collection = paginator.items.map do |item|
21
- facet_item_presenter(item, facet_config, facet_field)
22
- end
23
-
24
- render(facet_item_component_class(facet_config).with_collection(collection, wrapping_element: wrapping_element))
25
- end
26
- Blacklight.deprecation.deprecate_methods(self, render_facet_limit_list: 'Call e.g. `render facet_items` instead')
27
-
28
10
  def facet_items(wrapping_element: :li, **item_args)
29
11
  facet_item_component_class.with_collection(facet_item_presenters, wrapping_element: wrapping_element, **item_args)
30
12
  end
@@ -39,12 +21,12 @@ module Blacklight
39
21
  @facet_field.paginator&.items&.any?
40
22
  end
41
23
 
42
- def facet_item_presenter(facet_item, deprecated_facet_config = nil, facet_field = nil)
43
- (deprecated_facet_config || facet_config).item_presenter.new(facet_item, deprecated_facet_config || facet_config, helpers, facet_field || @facet_field.key)
24
+ def facet_item_presenter(facet_item)
25
+ facet_config.item_presenter.new(facet_item, facet_config, helpers, @facet_field.key)
44
26
  end
45
27
 
46
- def facet_item_component_class(deprecated_facet_config = nil)
47
- (deprecated_facet_config || facet_config).item_component
28
+ def facet_item_component_class
29
+ facet_config.item_component
48
30
  end
49
31
 
50
32
  def facet_config
@@ -10,10 +10,10 @@
10
10
 
11
11
  <div class="sort-options btn-group">
12
12
  <% if @facet_field.paginator.sort == 'index' -%>
13
- <span class="active az btn btn-outline-secondary"><%= t('blacklight.search.facets.sort.index') %></span>
14
- <%= helpers.link_to(t('blacklight.search.facets.sort.count'), sort_facet_url('count'), class: "sort_change numeric btn btn-outline-secondary", data: { blacklight_modal: "preserve" }) %>
13
+ <span class="active az <%= @button_classes %>"><%= t('blacklight.search.facets.sort.index') %></span>
14
+ <%= helpers.link_to(t('blacklight.search.facets.sort.count'), sort_facet_url('count'), class: "sort_change numeric #{@button_classes}", data: { blacklight_modal: "preserve" }) %>
15
15
  <% elsif @facet_field.paginator.sort == 'count' -%>
16
- <%= helpers.link_to(t('blacklight.search.facets.sort.index'), sort_facet_url('index'), class: "sort_change az btn btn-outline-secondary", data: { blacklight_modal: "preserve" }) %>
17
- <span class="active numeric btn btn-outline-secondary"><%= t('blacklight.search.facets.sort.count') %></span>
16
+ <%= helpers.link_to(t('blacklight.search.facets.sort.index'), sort_facet_url('index'), class: "sort_change az #{@button_classes}", data: { blacklight_modal: "preserve" }) %>
17
+ <span class="active numeric <%= @button_classes %>"><%= t('blacklight.search.facets.sort.count') %></span>
18
18
  <% end -%>
19
19
  </div>
@@ -2,8 +2,9 @@
2
2
 
3
3
  module Blacklight
4
4
  class FacetFieldPaginationComponent < Blacklight::Component
5
- def initialize(facet_field:)
5
+ def initialize(facet_field:, button_classes: %w[btn btn-outline-secondary])
6
6
  @facet_field = facet_field
7
+ @button_classes = button_classes.join(' ')
7
8
  end
8
9
 
9
10
  def sort_facet_url(sort)
@@ -54,8 +54,8 @@ module Blacklight
54
54
  tag.span(label, class: "selected") +
55
55
  # remove link
56
56
  link_to(href, class: "remove", rel: "nofollow") do
57
- render(Blacklight::Icons::RemoveComponent.new) +
58
- tag.span(helpers.t(:'blacklight.search.facets.selected.remove'), class: 'sr-only visually-hidden')
57
+ render(Blacklight::Icons::RemoveComponent.new(aria_hidden: true)) +
58
+ tag.span(helpers.t(:'blacklight.search.facets.selected.remove'), class: 'visually-hidden')
59
59
  end
60
60
  end + render_facet_count(classes: ["selected"])
61
61
  end
@@ -32,7 +32,7 @@ module Blacklight
32
32
 
33
33
  id = "h-#{self.class.mint_id}" if @collapsing && has_items?
34
34
 
35
- content_tag @wrapping_element, role: 'treeitem', class: 'treeitem' do
35
+ content_tag @wrapping_element, class: 'treeitem' do
36
36
  concat(content_tag('span', class: "d-flex flex-row align-items-center") do
37
37
  concat facet_toggle_button(id) if has_items? && @collapsing
38
38
  concat content_tag('span', render(facet), class: "facet-values d-flex flex-row flex-grow-1 #{'facet-leaf-node' if has_items? && @collapsing}", id: id && "#{id}_label")
@@ -75,7 +75,7 @@ module Blacklight
75
75
  def toggle_icon(type)
76
76
  content_tag 'span', class: type do
77
77
  concat @icons[type]
78
- concat content_tag('span', t(type, scope: 'blacklight.search.facets.pivot'), class: 'sr-only visually-hidden')
78
+ concat content_tag('span', t(type, scope: 'blacklight.search.facets.pivot'), class: 'visually-hidden')
79
79
  end
80
80
  end
81
81
  end
@@ -1,27 +1,12 @@
1
1
  <% # main container for facets/limits menu -%>
2
2
  <%= content_tag :div, id: @id, class: 'facets sidenav facets-toggleable-md' do %>
3
3
  <div class="facets-header">
4
- <%= content_tag :h2, @title, class: 'facets-heading' if @title %>
4
+ <%= content_tag :h2, @title, class: 'facets-heading h4' if @title %>
5
5
 
6
- <%= content_tag :button,
7
- class: 'btn btn-outline-secondary facet-toggle-button d-block d-lg-none',
8
- type: 'button',
9
- data: {
10
- toggle: 'collapse',
11
- target: "##{@panel_id}",
12
- 'bs-toggle': 'collapse',
13
- 'bs-target': "##{@panel_id}"
14
- },
15
- aria: {
16
- controls: @panel_id,
17
- expanded: 'false',
18
- } do %>
19
- <span data-show-label><%= t('blacklight.search.facets.group.open') %></span>
20
- <span data-hide-label><%= t('blacklight.search.facets.group.close') %></span>
21
- <% end %>
6
+ <%= collapse_toggle_button(@panel_id) %>
22
7
  </div>
23
8
 
24
- <div id="<%= @panel_id %>" class="facets-collapse collapse">
9
+ <div id="<%= @panel_id %>" class="facets-collapse d-lg-block collapse accordion">
25
10
  <%= body %>
26
11
  </div>
27
12
  <% end %>
@@ -6,42 +6,26 @@ module Blacklight
6
6
  class FacetGroupComponent < Blacklight::Component
7
7
  renders_one :body
8
8
 
9
- # @param [Blacklight::Response] response
10
- # @param [Array<Blacklight::Configuration::FacetField>] fields facet fields to render
11
- # @param [String] title the title of the facet group section
12
9
  # @param [String] id a unique identifier for the group
13
- def initialize(id:, title: nil, fields: [], response: nil)
10
+ # @param [String] title the title of the facet group section
11
+ def initialize(id:, title: nil)
14
12
  @groupname = id
15
13
  @id = id ? "facets-#{id}" : 'facets'
16
14
  @title = title || I18n.t("blacklight.search.#{@id}.title")
17
15
  @panel_id = id ? "facet-panel-#{id}-collapse" : 'facet-panel-collapse'
16
+ end
18
17
 
19
- # deprecated variables
20
- @fields = fields
21
- @response = response
18
+ def collapse_toggle_button(panel_id)
19
+ render button_component.new(panel_id: panel_id)
22
20
  end
23
21
 
24
- # Provide fallback behavior for rendering this object without a body slot
25
- def before_render
26
- set_slot(:body, nil) { default_body } unless body?
22
+ def button_component
23
+ Blacklight::Response::FacetToggleButtonComponent
27
24
  end
28
25
 
29
26
  def render?
30
27
  body.present?
31
28
  end
32
-
33
- private
34
-
35
- # @deprecated
36
- def default_body
37
- Blacklight.deprecation.warn('Rendering the Blacklight::FacetGroupComponent without a body slot is deprecated.')
38
- render(Blacklight::FacetComponent.with_collection(@fields, response: @response))
39
- end
40
-
41
- # @deprecated
42
- def blacklight_config
43
- helpers.blacklight_config
44
- end
45
29
  end
46
30
  end
47
31
  end
@@ -0,0 +1,16 @@
1
+ <%= content_tag :button,
2
+ class: @classes,
3
+ type: 'button',
4
+ data: {
5
+ toggle: 'collapse',
6
+ target: "##{@panel_id}",
7
+ 'bs-toggle': 'collapse',
8
+ 'bs-target': "##{@panel_id}"
9
+ },
10
+ aria: {
11
+ controls: @panel_id,
12
+ expanded: 'false',
13
+ } do %>
14
+ <span data-show-label><%= t('blacklight.search.facets.group.open') %></span>
15
+ <span data-hide-label><%= t('blacklight.search.facets.group.close') %></span>
16
+ <% end %>
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Response
5
+ # Render the button that shows or collapses the facets on a narrow viewport
6
+ class FacetToggleButtonComponent < Blacklight::Component
7
+ # @param [String] panel_id
8
+ def initialize(panel_id:, classes: 'btn btn-outline-secondary facet-toggle-button d-block d-lg-none')
9
+ @panel_id = panel_id
10
+ @classes = classes
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,3 +1,3 @@
1
- <%= tag.nav class: 'paginate-section', **html_attr do %>
1
+ <%= tag.nav class: @classes, **html_attr do %>
2
2
  <%= pagination %>
3
3
  <% end %>
@@ -6,9 +6,10 @@ module Blacklight
6
6
  class PaginationComponent < Blacklight::Component
7
7
  # @param [Blacklight::Response] response
8
8
  # @param [Hash] html html options for the pagination container
9
- def initialize(response:, html: {}, **pagination_args)
9
+ def initialize(response:, html: {}, classes: 'paginate-section', **pagination_args)
10
10
  @response = response
11
11
  @html = html
12
+ @classes = classes
12
13
  @pagination_args = pagination_args
13
14
  end
14
15
 
@@ -22,6 +22,7 @@ module Blacklight
22
22
  param: @param,
23
23
  choices: @choices,
24
24
  id: @id,
25
+ classes: @classes,
25
26
  search_state: @search_state,
26
27
  selected: @selected
27
28
  ))
@@ -1,4 +1,4 @@
1
1
  <%= link_to url, title: label, aria: aria_attributes, class: "#{Array(@classes).join(' ')} view-type-#{ @key.to_s.parameterize } #{"active" if selected?}" do %>
2
2
  <%= icon %>
3
- <span class="caption"><%= label %></span>
3
+ <span class="caption visually-hidden"><%= label %></span>
4
4
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <div class="view-type">
2
- <span class="sr-only visually-hidden"><%= t('blacklight.search.view_title') %></span>
2
+ <span class="visually-hidden"><%= t('blacklight.search.view_title') %></span>
3
3
  <div class="view-type-group btn-group">
4
4
  <% views.each do |view| %>
5
5
  <%= view %>
@@ -1,9 +1,9 @@
1
- <label for="facet_suggest_<%= facet.key %>">
1
+ <label for="facet-suggest-<%= facet.key %>">
2
2
  <%= I18n.t('blacklight.search.facets.suggest.label', field_label: presenter&.label) %>
3
3
  </label>
4
- <%= text_field_tag "facet_suggest_#{facet.key}",
5
- nil,
6
- class: "facet-suggest form-control",
7
- data: {facet_field: facet.key},
8
- placeholder: I18n.t('blacklight.search.form.search.placeholder')
9
- %>
4
+ <input class="facet-suggest form-control"
5
+ id="facet-suggest-<%= facet.key %>"
6
+ data-facet-field="<%= facet.key %>"
7
+ name="facet_suggest_<%= facet.key %>"
8
+ placeholder="<%= I18n.t('blacklight.search.form.search.placeholder') %>">
9
+ </input>
@@ -11,10 +11,6 @@ module Blacklight
11
11
  private
12
12
 
13
13
  attr_accessor :facet, :presenter
14
-
15
- def render?
16
- facet&.suggest
17
- end
18
14
  end
19
15
  end
20
16
  end
@@ -1,2 +1,2 @@
1
- <span class="sr-only visually-hidden"><%= t('blacklight.search.per_page.title') %></span>
1
+ <span class="visually-hidden"><%= t('blacklight.search.per_page.title') %></span>
2
2
  <%= dropdown %>
@@ -23,6 +23,7 @@ module Blacklight
23
23
  param: :per_page,
24
24
  choices: per_page_options_for_select,
25
25
  id: 'per_page-dropdown',
26
+ classes: ['mx-1'],
26
27
  search_state: @search_state,
27
28
  selected: current_per_page,
28
29
  interpolation: :count
@@ -1,7 +1,7 @@
1
1
  <search>
2
2
  <% facet_group_names.each do |groupname| %>
3
3
  <% fields = facet_fields_in_group(groupname) %>
4
- <%= render group_component_class.new(id: groupname, fields: fields, response: response) do |component| %>
4
+ <%= render group_component_class.new(id: groupname) do |component| %>
5
5
  <% component.with_body do %>
6
6
  <%= render Blacklight::FacetComponent.with_collection(fields, response: response) %>
7
7
  <% end %>
@@ -6,7 +6,7 @@ module Blacklight
6
6
  def initialize(blacklight_config:, response:, view_config:)
7
7
  @blacklight_config = blacklight_config
8
8
  @response = response
9
- @group_component_class = view_config.facet_group_component || Blacklight::Response::FacetGroupComponent
9
+ @group_component_class = view_config.facet_group_component
10
10
  end
11
11
 
12
12
  attr_reader :group_component_class, :response
@@ -2,7 +2,7 @@
2
2
  <%= form_with url: @url, local: true, method: @method, class: @classes.join(' '), scope: @prefix, role: 'search', **@form_options do |f| %>
3
3
  <%= render Blacklight::HiddenSearchStateComponent.new(params: @params) %>
4
4
  <% if search_fields.length > 1 %>
5
- <%= f.label :search_field, scoped_t('search_field.label'), class: 'sr-only visually-hidden' %>
5
+ <%= f.label :search_field, scoped_t('search_field.label'), class: 'visually-hidden' %>
6
6
  <% end %>
7
7
  <% before_input_groups.each do |input_group| %>
8
8
  <%= input_group %>
@@ -20,9 +20,9 @@
20
20
  <%= f.hidden_field :search_field, value: search_fields.first.last %>
21
21
  <% end %>
22
22
 
23
- <%= f.label @query_param, scoped_t('search.label'), class: 'sr-only visually-hidden' %>
23
+ <%= f.label @query_param, scoped_t('search.label'), class: 'visually-hidden' %>
24
24
  <% if autocomplete_path.present? %>
25
- <auto-complete src="<%= autocomplete_path %>" for="autocomplete-popup" class="search-autocomplete-wrapper <%= rounded_border_class %>">
25
+ <auto-complete src="<%= autocomplete_path %>" for="autocomplete-popup" class="search-autocomplete-wrapper form-control <%= rounded_border_class %>">
26
26
  <%= f.search_field @query_param, value: @q, placeholder: scoped_t('search.placeholder'), class: "search-q q form-control #{rounded_border_class}", autofocus: @autofocus, aria: { label: scoped_t('search.label'), autocomplete: 'list', controls: 'autocomplete-popup' } %>
27
27
  <ul id="autocomplete-popup" class="dropdown-menu" role="listbox" aria-label="<%= scoped_t('search.label') %>" hidden></ul>
28
28
  </auto-complete>
@@ -11,7 +11,7 @@ module Blacklight
11
11
  def initialize(
12
12
  url:, params:,
13
13
  advanced_search_url: nil,
14
- classes: ['search-query-form'], prefix: nil,
14
+ classes: %w[search-query-form col-md-12 col-lg-8], prefix: nil,
15
15
  method: 'GET', q: nil, query_param: :q,
16
16
  search_field: nil, autocomplete_path: nil,
17
17
  autofocus: nil, i18n: { scope: 'blacklight.search.form' },
@@ -63,7 +63,7 @@ module Blacklight
63
63
  def rounded_border_class
64
64
  return 'rounded-0' if search_fields.length > 1
65
65
 
66
- 'rounded-left rounded-start'
66
+ 'rounded-start'
67
67
  end
68
68
 
69
69
  private
@@ -8,8 +8,8 @@ module Blacklight
8
8
  end
9
9
 
10
10
  def call
11
- tag.button(class: 'btn btn-primary search-btn', type: 'submit', id: @id) do
12
- tag.span(@text, class: "visually-hidden-sm me-sm-1 submit-search-text") +
11
+ tag.button(class: 'btn btn-primary search-btn', type: 'submit', id: @id, aria: { label: @text }) do
12
+ tag.span(@text, class: "d-none d-md-inline me-sm-1 submit-search-text", aria: { hidden: true }) +
13
13
  render(Blacklight::Icons::SearchComponent.new)
14
14
  end
15
15
  end
@@ -1,4 +1,4 @@
1
- <div id="appliedParams" class="clearfix constraints-container">
2
- <%= render 'start_over' %>
1
+ <div id="appliedParams" class="clearfix constraints-container mb-2">
2
+ <%= start_over %>
3
3
  <%= link_back_to_catalog class: 'btn btn-outline-secondary' %>
4
4
  </div>
@@ -2,12 +2,21 @@
2
2
 
3
3
  module Blacklight
4
4
  module SearchContext
5
+ # This is displayed on the show page when the user has a search session.
5
6
  class ServerAppliedParamsComponent < Blacklight::Component
6
7
  delegate :current_search_session, :link_back_to_catalog, to: :helpers
7
8
 
8
9
  def render?
9
10
  current_search_session
10
11
  end
12
+
13
+ def start_over
14
+ render start_over_component.new
15
+ end
16
+
17
+ def start_over_component
18
+ Blacklight::StartOverButtonComponent
19
+ end
11
20
  end
12
21
  end
13
22
  end
@@ -1,4 +1,4 @@
1
- <nav id="skip-link" class="visually-hidden-focusable sr-only sr-only-focusable" aria-label="<%= t('blacklight.skip_links.label') %>">
1
+ <nav id="skip-link" class="visually-hidden-focusable" aria-label="<%= t('blacklight.skip_links.label') %>">
2
2
  <div class="container-xl">
3
3
  <%= link_to_main %>
4
4
  <%= link_to_search %>
@@ -3,11 +3,11 @@
3
3
  module Blacklight
4
4
  class SkipLinkComponent < Blacklight::Component
5
5
  def link_to_search
6
- link_to t('blacklight.skip_links.search_field'), search_id, class: link_classes
6
+ render skip_link_item_component.new(text: t('blacklight.skip_links.search_field'), href: search_id)
7
7
  end
8
8
 
9
9
  def link_to_main
10
- link_to t('blacklight.skip_links.main_content'), '#main-container', class: link_classes
10
+ render skip_link_item_component.new(text: t('blacklight.skip_links.main_content'), href: '#main-container')
11
11
  end
12
12
 
13
13
  def search_id
@@ -16,8 +16,12 @@ module Blacklight
16
16
  '#q'
17
17
  end
18
18
 
19
+ delegate :blacklight_config, to: :helpers
20
+ delegate :skip_link_item_component, to: :blacklight_config
21
+
19
22
  def link_classes
20
- 'd-inline-flex p-2 m-1'
23
+ Blacklight.deprecation.warn("Use SkipLinkItemComponent instead")
24
+ 'visually-hidden-focusable rounded-bottom py-2 px-3'
21
25
  end
22
26
  end
23
27
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ class SkipLinkItemComponent < Blacklight::Component
5
+ def initialize(text:, href:)
6
+ @text = text
7
+ @href = href
8
+ end
9
+
10
+ def call
11
+ link_to @text, @href, class: link_classes
12
+ end
13
+
14
+ def link_classes
15
+ 'd-inline-flex py-2 px-3'
16
+ end
17
+ end
18
+ end
@@ -1,7 +1,7 @@
1
1
  <nav class="navbar navbar-expand-md navbar-dark bg-dark topbar" aria-label="<%= aria_label %>">
2
2
  <div class="<%= container_classes %>">
3
3
  <%= logo_link %>
4
- <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-bs-toggle="collapse" data-target="#user-util-collapse" data-bs-target="#user-util-collapse" aria-controls="user-util-collapse" aria-expanded="false" aria-label="Toggle navigation">
4
+ <button class="navbar-toggler" type="button" data-toggle="collapse" data-bs-toggle="collapse" data-target="#user-util-collapse" data-bs-target="#user-util-collapse" aria-controls="user-util-collapse" aria-expanded="false" aria-label="Toggle navigation">
5
5
  <span class="navbar-toggler-icon"></span>
6
6
  </button>
7
7
 
@@ -83,10 +83,11 @@ module Blacklight::Catalog
83
83
  @facet = blacklight_config.facet_fields[params[:id]]
84
84
  raise ActionController::RoutingError, 'Not Found' unless @facet
85
85
 
86
- @response = if params[:query_fragment].present?
86
+ query_fragment = params[:query_fragment] || ''
87
+ @response = if query_fragment.present?
87
88
  search_service.facet_suggest_response(@facet.key, params[:query_fragment])
88
89
  else
89
- search_service.facet_field_response(@facet.key)
90
+ @response = search_service.facet_field_response(@facet.key)
90
91
  end
91
92
  @display_facet = @response.aggregations[@facet.field]
92
93