Skip to content

Commit

Permalink
Refactor search component (#487)
Browse files Browse the repository at this point in the history
* Quieten sass

* Componentise the search UI

To separate these components from external CSS and decouple it from the rest of the app, I've

- moved the styles to a separate components directory
- prefixed classes with `fmj-`
- removed hardcoded colours and URLs
- adopted the Block-Element-Modifier naming convention for consistency with GOV.UK and MOJ design systems

I'm hoping that by introducing this structure, we can make it easier to either

a) swap out the component if one is added to one of the design systems,
or
b) contribute back to the MOJ design system later if it meets the contribution criteria

Originally I was planning to also extract javascript enhancements we've
made to search, but I ended up leaving these as they are, because they
are unrelated to the search bar component itself, and neither of them
are needed on more than one page.

* Add landmark and usage instructions to search
  • Loading branch information
MatMoore authored Jun 25, 2024
1 parent dd27899 commit fc0615b
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 89 deletions.
7 changes: 4 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,10 @@ cython_debug/

#static files dirs
staticfiles/
static/
!/static/assets/js/enhanced-glossary.js
!/static/assets/js/enhanced-search.js
static/assets/*
!/static/assets/js/
/static/assets/js/*.min.js
/static/assets/js/*.map

node_modules

Expand Down
8 changes: 6 additions & 2 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@
{
"path": "detect_secrets.filters.allowlist.is_line_allowlisted"
},
{
"path": "detect_secrets.filters.common.is_baseline_file",
"filename": ".secrets.baseline"
},
{
"path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies",
"min_level": 2
Expand Down Expand Up @@ -114,9 +118,9 @@
"filename": "templates/base/base.html",
"hashed_secret": "f6538b22f89b1e2b05570de751f2932c6bca9969",
"is_verified": false,
"line_number": 40
"line_number": 38
}
]
},
"generated_at": "2024-02-21T10:23:47Z"
"generated_at": "2024-06-24T11:27:46Z"
}
6 changes: 4 additions & 2 deletions scripts/import-static.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
cd app
if [[ -d app ]]; then
cd app
fi

cp -a node_modules/govuk-frontend/dist/govuk/assets/. static/assets \
&& cp -a node_modules/@ministryofjustice/frontend/moj/assets/images/. static/assets/images
Expand All @@ -7,4 +9,4 @@ cp node_modules/govuk-frontend/dist/govuk/govuk-frontend.min.js static/assets/js
&& cp node_modules/govuk-frontend/dist/govuk/govuk-frontend.min.js.map static/assets/js/govuk-frontend.min.js.map \
&& cp node_modules/@ministryofjustice/frontend/moj/all.jquery.min.js static/assets/js/moj-frontend.min.js

sass --load-path=. scss:static/assets/css
sass -q --load-path=. scss:static/assets/css
52 changes: 27 additions & 25 deletions scss/base.scss
Original file line number Diff line number Diff line change
@@ -1,48 +1,50 @@
$govuk-assets-path: '/static/assets/';
$moj-assets-path: '/static/assets/';
$govuk-assets-path: "/static/assets/";
$moj-assets-path: "/static/assets/";
$fmj-images-path: "/static/assets/images";

// Removes need to put classes on all elements
$govuk-global-styles: true;

@import "node_modules/govuk-frontend/dist/govuk/all";
@import "node_modules/@ministryofjustice/frontend/moj/all";
@import "./components/search";
@import "./glossary";
@import "./details";

.js-required {
display: none;
display: none;
}

mark {
background-color: inherit;
color: inherit;
@include govuk-typography-weight-bold($important: false);
background-color: inherit;
color: inherit;
@include govuk-typography-weight-bold($important: false);
}

.extra-skip-link:active, .extra-skip-link:focus {
margin-bottom: govuk-spacing(3) !important;
.extra-skip-link:active,
.extra-skip-link:focus {
margin-bottom: govuk-spacing(3) !important;
}

.column-description {
@include govuk-media-query($from: desktop) {
max-width: calc($govuk-page-width / 2);
overflow-wrap: break-word;
}
@include govuk-media-query($from: desktop) {
max-width: calc($govuk-page-width / 2);
overflow-wrap: break-word;
}
}

.wide-table {
table-layout: fixed;
width: 100%;
overflow-wrap: break-word;
table-layout: fixed;
width: 100%;
overflow-wrap: break-word;
}

code {
font-family: monaco, Consolas, "Lucida Console", monospace;
@include govuk-font-size($size: 16); /* Slightly smaller font size */
background-color: govuk-colour("light-grey");
border: 1px solid #ddd;
border-radius: 2px; /* Rounded corners */
padding: 1px 3px; /* Padding around the text */
color: govuk-colour("black");
font-family: monaco, Consolas, "Lucida Console", monospace;
@include govuk-font-size($size: 16); /* Slightly smaller font size */
background-color: govuk-colour("light-grey");
border: 1px solid #ddd;
border-radius: 2px; /* Rounded corners */
padding: 1px 3px; /* Padding around the text */
color: govuk-colour("black");
}

@import './glossary';
@import './details';
74 changes: 74 additions & 0 deletions scss/components/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Search component

This enhances a [GOV.UK text input](https://design-system.service.gov.uk/components/text-input/) to act as a search input.

It's intended for use as a service-wide search or as a way of filtering long manuals or lists.

## Similar components elsewhere

- [GOV.UK publishing components search](https://components.publishing.service.gov.uk/component-guide/search)
- [Explore education statistics search](https://github.com/dfe-analytical-services/explore-education-statistics/blob/8a9aa729636eade2808895ad71a56bcb984d3c53/src/explore-education-statistics-common/src/components/form/FormSearchBar.module.scss)
- [MOJ search](https://design-patterns.service.justice.gov.uk/components/search/) and [icon](https://github.com/dfe-analytical-services/explore-education-statistics/blob/8a9aa729636eade2808895ad71a56bcb984d3c53/src/explore-education-statistics-common/src/components/SearchIcon.tsx#L4)
- [MOJ filter](https://design-patterns.service.justice.gov.uk/components/filter/)

## Expected behaviours

- Clearable via the "X" button or pressing escape
- Focusable, with a focus outline

## Usage

The search box should:

- be used inside a form or other element with `role="search"`, to indicate it as a [search landmark](https://www.w3.org/WAI/ARIA/apg/practices/landmark-regions/).
- have a visually hidden label to identify the search functionality

### With no search icon

This variant should be used only for search-as-you-type behaviour that does not require submitting a form.

See `enhanced-glossary.js`.

```html
<div class="fmj-search govuk-form-group">
<label for="filter-input" class="govuk-label">Filter this page</label>
<input class="govuk-input" type="search" placeholder="Filter this page" />
</div>
```

### With an integrated search button

This variant submits the form when the button is pressed or the user presses enter.

```html
<form action="" method="get" role="search" class="govuk-!-margin-bottom-4">
<div class="fmj-search fmj-search--compact govuk-form-group">
<label
for="search-input"
class="govuk-label govuk-visually-hidden-focusable"
>Search query</label
>
<input class="search-input govuk-input" type="search" />
<button type="submit">
<svg
aria-hidden="true"
focusable="false"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 36 36"
width="40"
height="40"
>
<path
d="M25.7 24.8L21.9 21c.7-1 1.1-2.2 1.1-3.5 0-3.6-2.9-6.5-6.5-6.5S10 13.9 10 17.5s2.9 6.5 6.5 6.5c1.6 0 3-.6 4.1-1.5l3.7 3.7 1.4-1.4zM12 17.5c0-2.5 2-4.5 4.5-4.5s4.5 2 4.5 4.5-2 4.5-4.5 4.5-4.5-2-4.5-4.5z"
fill="currentColor"
></path>
</svg>
<label
for="search-button"
class="govuk-label govuk-visually-hidden-focusable"
>Search</label
>
</button>
</div>
</form>
```
57 changes: 57 additions & 0 deletions scss/components/_search.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Base enhancements to search fields
.fmj-search {
.govuk-input[type="search"] {
&:focus {
z-index: 1;
}

// Enhance the close button.
// Note: this is a non-standard CSS feature and will not do anything in Firefox.
// https://caniuse.com/mdn-css_selectors_-webkit-search-cancel-button
&::-webkit-search-cancel-button {
-webkit-appearance: none;
background-image: url(#{$fmj-images-path}/icon-close-cross-black.svg);
background-position: center;
background-repeat: no-repeat;
cursor: pointer;
height: 15px;
margin-left: 0;
margin-right: 2px;
width: 15px;
}
}
}

// Variant with search button adjacent to the input
.fmj-search--compact {
display: flex;

.govuk-input[type="search"] {
border-right-width: 0;

&:focus {
border-right-width: 2px;
z-index: 1;
}
}

svg {
height: 100%;
}

button {
background-color: govuk-colour("blue");
border: 0;
color: govuk-colour("white");
cursor: pointer;
height: 40px;
margin-bottom: 0;
padding: 0;
width: 40px;
}

button:focus {
box-shadow: inset 0 0 0 4px govuk-colour("black");
outline: 3px solid govuk-colour("yellow");
}
}
54 changes: 0 additions & 54 deletions scss/search.scss

This file was deleted.

1 change: 0 additions & 1 deletion templates/base/head.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
<link rel="mask-icon" href="{% static 'assets/images/govuk-icon-mask.svg' %}" color="blue">
<link rel="apple-touch-icon" href="{% static 'assets/images/govuk-icon-180.png' %}">
<link rel="manifest" href="{% static 'assets/manifest.json' %}">
<link rel="stylesheet" type="text/css" href="{% static 'assets/css/search.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'assets/css/base.css' %}">
<meta property="og:image" content="{% static 'assets/images/govuk-opengraph-image.png' %}">
</head>
2 changes: 1 addition & 1 deletion templates/glossary.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<h1 class="govuk-heading-l">{{h1_value}}</h1>
</div>
<div class="govuk-grid-column-three-quarters">
<div class="govuk-form-group govuk-!-margin-bottom-8 js-required">
<div role="search" class="fmj-search govuk-form-group govuk-!-margin-bottom-8 js-required">
<label for="filter-input" class="govuk-label govuk-visually-hidden-focusable">Filter this page (the content will be updated as you type)</label>
<input class="govuk-input" id="filter-input" type="search" placeholder="Filter this page">
</div>
Expand Down
2 changes: 1 addition & 1 deletion templates/search.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<form action="{% url 'home:search' %}" method="get" role="search" class="search__form govuk-!-margin-bottom-4" id="searchform">
<div class="govuk-form-group">
<h1 class="govuk-heading-l">{{h1_value}}</h1>
<div class="search-container">
<div class="fmj-search fmj-search--compact">
<label for="{{ form.query.id_for_label }}" class="govuk-label govuk-visually-hidden-focusable">Search MOJ Data</label>
{{ form.query }}
<button class="search-button" type="submit" id="search-button">
Expand Down

0 comments on commit fc0615b

Please sign in to comment.