Skip to content

Commit

Permalink
Make filters collapsible
Browse files Browse the repository at this point in the history
This builds on the [Accordion component](https://components.publishing.service.gov.uk/component-guide/accordion)
and applies some custom styling. I’ve also updated the tests to check
the panels are expanded when a filter is present.
  • Loading branch information
pezholio committed Nov 11, 2024
1 parent 9f41b43 commit 51a8e8a
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 60 deletions.
1 change: 1 addition & 0 deletions app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

//= require govuk_publishing_components/dependencies
//= require govuk_publishing_components/analytics-ga4
//= require govuk_publishing_components/components/accordion
//= require govuk_publishing_components/components/copy-to-clipboard
//= require govuk_publishing_components/components/govspeak
//= require govuk_publishing_components/components/reorderable-list
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
@import "components/filter-options-component";
@import "components/timeline-component";
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
.app-c-content-block-manager-filter-options {
.govuk-accordion__section-toggle,
.govuk-accordion__controls .govuk-accordion-nav__chevron {
@include govuk-visually-hidden;
}

@mixin chevron($dir) {
&:before {
border-style: solid;
border-width: 0.2em 0.2em 0 0;
content: "";
display: inline-block;
height: 0.45em;
left: 0.15em;
position: relative;
vertical-align: top;
width: 0.45em;

@include govuk-responsive-margin(3, "right");

@if $dir == "down" {
top: 0.2em;
transform: rotate(135deg);
}

@if $dir == "up" {
top: 0.35em;
transform: rotate(-45deg);
}
}
}

.govuk-accordion__controls {
.govuk-accordion__show-all {
.govuk-accordion__show-all-text {
@include govuk-font($size: 19, $weight: bold);
color: govuk-colour("black");
@include chevron("down");
}

&[aria-expanded="true"] {
.govuk-accordion__show-all-text {
@include chevron("up");
}
}
}
}

.govuk-accordion__section-button {
.govuk-accordion__section-heading-text {
@include govuk-font($size: 19, $weight: bold);

@include chevron("down");
}

&[aria-expanded="true"] {
.govuk-accordion__section-heading-text {
@include chevron("up");
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,63 @@
<%= form_with url: helpers.content_block_manager.content_block_manager_content_block_documents_path, method: :get do %>
<%= render "govuk_publishing_components/components/input", {
label: {
text: "Keyword",
bold: true,
},
hint: 'For example, "driving standards"',
name: "keyword",
id: "keyword_filter",
value: !@filters.nil? && @filters[:keyword],
} %>

<%= render "govuk_publishing_components/components/checkboxes", {
heading: "Content block type",
heading_size: "s",
no_hint_text: true,
id: "block_type",
name: "block_type[]",
items: items_for_block_type,
} %>

<%= render "components/select_with_search", {
id: "lead_organisation",
name: "lead_organisation",
label: "Lead organisation",
heading_size: "s",
include_blank: false,
options: options_for_lead_organisation,
<%= form_with url: helpers.content_block_manager.content_block_manager_content_block_documents_path, method: :get, class: "app-c-content-block-manager-filter-options" do %>
<%= render "govuk_publishing_components/components/accordion", {
disable_ga4: true,
items: [
{
heading: {
text: "Search by keyword",
},
content: {
html: (
render "govuk_publishing_components/components/input", {
label: {
text: "Keyword",
bold: true,
},
hint: 'For example, "driving standards"',
name: "keyword",
id: "keyword_filter",
value: @filters.present? && @filters[:keyword],
}
),
},
expanded: @filters&.fetch(:keyword, nil).present?,
},
{
heading: {
text: "Content block type",
},
content: {
html: (
render "govuk_publishing_components/components/checkboxes", {
heading: "Content block type",
visually_hide_heading: true,
heading_size: "s",
no_hint_text: true,
id: "block_type",
name: "block_type[]",
items: items_for_block_type,
}
),
},
expanded: @filters&.fetch(:block_type, nil).present?,
},
{
heading: {
text: "Lead organisation",
},
content: {
html: (
render "components/select_with_search", {
id: "lead_organisation",
name: "lead_organisation",
include_blank: false,
options: options_for_lead_organisation,
}
),
},
expanded: @filters&.fetch(:lead_organisation, nil).present?,
},
],
} %>

<%= render "govuk_publishing_components/components/button", {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,59 +1,84 @@
require "test_helper"

class ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponentTest < ViewComponent::TestCase
test "adds value of keyword to text input from filter" do
render_inline(ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent.new(
filters: { keyword: "ministry defense" },
))
extend Minitest::Spec::DSL

let(:helper_mock) { mock }

before do
ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent.any_instance.stubs(:helpers).returns(helper_mock)
helper_mock.stubs(:content_block_manager).returns(helper_mock)
helper_mock.stubs(:content_block_manager_content_block_documents_path).returns("path")

helper_mock.stubs(:taggable_organisations_container).returns(
[["Department of Placeholder", 1], ["Ministry of Example", 2]],
)

ContentBlockManager::ContentBlock::Schema.stubs(:valid_schemas).returns(%w[email_address postal_address])
end

it "collapses all sections by default" do
render_inline(
ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent.new(
filters: {},
),
)
assert_selector ".govuk-accordion__section--expanded", count: 0
end

it "adds value of keyword to text input from filter" do
render_inline(
ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent.new(
filters: { keyword: "ministry defense" },
),
)

assert_selector ".govuk-accordion__section--expanded", count: 1
assert_selector ".govuk-accordion__section--expanded", text: "Keyword"
assert_selector "input[name='keyword'][value='ministry defense']"
end

test "renders checkbox items for all valid schemas" do
ContentBlockManager::ContentBlock::Schema.expects(:valid_schemas).returns(%w[email_address postal_address])
render_inline(ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent.new(
filters: {},
))
it "renders checkbox items for all valid schemas" do
render_inline(
ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent.new(
filters: {},
),
)

assert_selector "input[type='checkbox'][name='block_type[]'][value='email_address']"
assert_selector "input[type='checkbox'][name='block_type[]'][value='postal_address']"
end

test "checks checkbox items if checked in filters" do
ContentBlockManager::ContentBlock::Schema.expects(:valid_schemas).returns(%w[email_address postal_address])
render_inline(ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent.new(
filters: { block_type: %w[email_address] },
))
it "checks checkbox items if checked in filters" do
render_inline(
ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent.new(
filters: { block_type: %w[email_address] },
),
)

assert_selector ".govuk-accordion__section--expanded", count: 1
assert_selector ".govuk-accordion__section--expanded", text: "Content block type"

assert_selector "input[type='checkbox'][name='block_type[]'][value='email_address'][checked]"
assert_selector "input[type='checkbox'][name='block_type[]'][value='postal_address']"
end

test "returns organisations with an 'all organisations' option" do
helper_mock = mock
ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent.any_instance.stubs(:helpers).returns(helper_mock)
helper_mock.stubs(:content_block_manager).returns(helper_mock)
helper_mock.stubs(:content_block_manager_content_block_documents_path).returns("path")
helper_mock.stubs(:taggable_organisations_container).returns(
[["Department of Placeholder", 1], ["Ministry of Example", 2]],
)
it "returns organisations with an 'all organisations' option" do
render_inline(ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent.new(filters: {}))

assert_selector "select[name='lead_organisation']"
assert_selector "option[selected='selected'][value='']"
end

test "selects organisation if selected in filters" do
helper_mock = mock
ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent.any_instance.stubs(:helpers).returns(helper_mock)
helper_mock.stubs(:content_block_manager).returns(helper_mock)
helper_mock.stubs(:content_block_manager_content_block_documents_path).returns("path")
helper_mock.stubs(:taggable_organisations_container).returns(
[["Department of Placeholder", 1], ["Ministry of Example", 2]],
it "selects organisation if selected in filters" do
render_inline(
ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent.new(
filters: { lead_organisation: "2" },
),
)
render_inline(ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent.new(
filters: { lead_organisation: "2" },
))

assert_selector ".govuk-accordion__section--expanded", count: 1
assert_selector ".govuk-accordion__section--expanded", text: "Lead organisation"

assert_selector "select[name='lead_organisation']"
assert_selector "option[selected='selected'][value=2]"
Expand Down

0 comments on commit 51a8e8a

Please sign in to comment.