From 70bb412c4f12a55717ccf92f4b09d737f49d4e01 Mon Sep 17 00:00:00 2001 From: Paul Steven Date: Mon, 13 Apr 2026 15:58:40 +0100 Subject: [PATCH 1/9] Add quick filters component files --- docs/components/quick-filters.md | 14 +++++ docs/examples/quick-filters/default.njk | 16 ++++++ src/components/quick-filters/_index.scss | 67 +++++++++++++++++++++++ src/components/quick-filters/macro.njk | 3 + src/components/quick-filters/template.njk | 40 ++++++++++++++ 5 files changed, 140 insertions(+) create mode 100644 docs/components/quick-filters.md create mode 100644 docs/examples/quick-filters/default.njk create mode 100644 src/components/quick-filters/_index.scss create mode 100644 src/components/quick-filters/macro.njk create mode 100644 src/components/quick-filters/template.njk diff --git a/docs/components/quick-filters.md b/docs/components/quick-filters.md new file mode 100644 index 0000000..59e021f --- /dev/null +++ b/docs/components/quick-filters.md @@ -0,0 +1,14 @@ +--- +title: Quick Filters +description: A horizontal list of buttons used to filter content or results. +layout: layouts/component.njk +tags: + - component +--- + +## Example + +{% example "quick-filters/default.njk" %} + +## When to use this component +Use the Quick Filters component when you have a list of items that can be categorized into clear, mutually exclusive groups. diff --git a/docs/examples/quick-filters/default.njk b/docs/examples/quick-filters/default.njk new file mode 100644 index 0000000..706c3b0 --- /dev/null +++ b/docs/examples/quick-filters/default.njk @@ -0,0 +1,16 @@ +--- +layout: layouts/example.njk +title: Quick Filters Default +description: A standard example of the quick filters component. +arguments: quick-filters +--- +{% from 'tel/components/quick-filters/macro.njk' import quickFilters %} + +{{ quickFilters({ + heading: "Filter by level:", + tags: [ + { label: "Beginner", value: "beginner" }, + { label: "Intermediate", value: "intermediate" }, + { label: "Advanced", value: "advanced" } + ] +}) }} diff --git a/src/components/quick-filters/_index.scss b/src/components/quick-filters/_index.scss new file mode 100644 index 0000000..74458b6 --- /dev/null +++ b/src/components/quick-filters/_index.scss @@ -0,0 +1,67 @@ + +@import "nhsuk/index"; +.quick-filters { + &__list { + list-style-type: none; + padding-left: 0; + margin-top: 0; + display: flex; + flex-direction: row; + align-items: center; + flex-wrap: wrap; + margin-bottom: nhsuk-spacing(2); + } + + &__list-heading { + @include nhsuk-font(16, $weight: bold); + margin-right: 8px; + } + + &__list-item { + display: flex; + align-items: center; + min-height: 44px; + margin-bottom: nhsuk-spacing(2); + padding: 0 nhsuk-spacing(2); + + &:hover { + background-color: nhsuk-colour('grey-4'); + border-radius: $nhsuk-border-radius; + } + } + + &__button { + @include nhsuk-font($size: 16, $weight: bold, $line-height: 1); + display: inline-block; + padding: 4px 14px; + border: 1px solid nhsuk-colour('grey-3'); + border-radius: 3px; + background-color: nhsuk-colour('white'); + color: nhsuk-colour('black'); + text-decoration: none; + + &:visited { + color: nhsuk-colour('black'); + } + + &:focus { + @include nhsuk-focused-button; + border: 2px solid; + box-shadow: none; + } + + &--active { + padding: 4px 6px 4px 5px; + background-color: nhsuk-tint(nhsuk-colour('blue'), 80%); + border-color: nhsuk-shade(nhsuk-colour('blue'), 30%); + color: nhsuk-shade(nhsuk-colour('blue'), 30%); + + &:before { + // The checkmark icon + content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='10' viewBox='0 0 12 10' fill='none'%3E%3Cpath d='M1.5 5.45455L4.83333 8L10.5 1' stroke='%23004281' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E"); + display: inline-block; + margin-right: 4px; + } + } + } +} diff --git a/src/components/quick-filters/macro.njk b/src/components/quick-filters/macro.njk new file mode 100644 index 0000000..14e6e36 --- /dev/null +++ b/src/components/quick-filters/macro.njk @@ -0,0 +1,3 @@ +{% macro quickFilters(params) %} + {%- include "./template.njk" -%} +{% endmacro %} diff --git a/src/components/quick-filters/template.njk b/src/components/quick-filters/template.njk new file mode 100644 index 0000000..acf5d52 --- /dev/null +++ b/src/components/quick-filters/template.njk @@ -0,0 +1,40 @@ + From 066eb42b346d7fc7e8fdc8cf2d8b6421b2a6cf04 Mon Sep 17 00:00:00 2001 From: Paul Steven Date: Mon, 13 Apr 2026 17:20:11 +0100 Subject: [PATCH 2/9] Add tel namespace and misc updates --- docs/examples/quick-filters/default.njk | 4 ++-- src/all.scss | 2 +- src/components/quick-filters/_index.scss | 21 +++++++++++-------- src/components/quick-filters/macro.njk | 2 +- src/components/quick-filters/template.njk | 25 +++++++++++------------ 5 files changed, 28 insertions(+), 26 deletions(-) diff --git a/docs/examples/quick-filters/default.njk b/docs/examples/quick-filters/default.njk index 706c3b0..17d9580 100644 --- a/docs/examples/quick-filters/default.njk +++ b/docs/examples/quick-filters/default.njk @@ -4,9 +4,9 @@ title: Quick Filters Default description: A standard example of the quick filters component. arguments: quick-filters --- -{% from 'tel/components/quick-filters/macro.njk' import quickFilters %} +{% from 'tel/components/quick-filters/macro.njk' import telQuickFilters %} -{{ quickFilters({ +{{ telQuickFilters({ heading: "Filter by level:", tags: [ { label: "Beginner", value: "beginner" }, diff --git a/src/all.scss b/src/all.scss index c7568bf..8764594 100644 --- a/src/all.scss +++ b/src/all.scss @@ -7,4 +7,4 @@ // 3. Your Custom Components @import "components/hello-world/hello-world"; - +@import "components/quick-filters/index"; diff --git a/src/components/quick-filters/_index.scss b/src/components/quick-filters/_index.scss index 74458b6..71f5625 100644 --- a/src/components/quick-filters/_index.scss +++ b/src/components/quick-filters/_index.scss @@ -1,6 +1,6 @@ - @import "nhsuk/index"; -.quick-filters { + +.tel-quick-filters { &__list { list-style-type: none; padding-left: 0; @@ -9,20 +9,22 @@ flex-direction: row; align-items: center; flex-wrap: wrap; + gap: nhsuk-spacing(2); margin-bottom: nhsuk-spacing(2); } &__list-heading { @include nhsuk-font(16, $weight: bold); - margin-right: 8px; + margin-right: nhsuk-spacing(2); } - &__list-item { + // Double-classing here to beat global NHS 'ul > li' specificity without !important + &__list-item.tel-quick-filters__list-item { display: flex; align-items: center; min-height: 44px; - margin-bottom: nhsuk-spacing(2); - padding: 0 nhsuk-spacing(2); + margin-bottom: 0; + padding: 0; &:hover { background-color: nhsuk-colour('grey-4'); @@ -32,7 +34,8 @@ &__button { @include nhsuk-font($size: 16, $weight: bold, $line-height: 1); - display: inline-block; + display: inline-flex; + align-items: center; padding: 4px 14px; border: 1px solid nhsuk-colour('grey-3'); border-radius: 3px; @@ -51,16 +54,16 @@ } &--active { - padding: 4px 6px 4px 5px; + padding: 4px 10px 4px 8px; background-color: nhsuk-tint(nhsuk-colour('blue'), 80%); border-color: nhsuk-shade(nhsuk-colour('blue'), 30%); color: nhsuk-shade(nhsuk-colour('blue'), 30%); &:before { - // The checkmark icon content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='10' viewBox='0 0 12 10' fill='none'%3E%3Cpath d='M1.5 5.45455L4.83333 8L10.5 1' stroke='%23004281' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E"); display: inline-block; margin-right: 4px; + vertical-align: middle; } } } diff --git a/src/components/quick-filters/macro.njk b/src/components/quick-filters/macro.njk index 14e6e36..4982196 100644 --- a/src/components/quick-filters/macro.njk +++ b/src/components/quick-filters/macro.njk @@ -1,3 +1,3 @@ -{% macro quickFilters(params) %} +{% macro telQuickFilters(params) %} {%- include "./template.njk" -%} {% endmacro %} diff --git a/src/components/quick-filters/template.njk b/src/components/quick-filters/template.njk index acf5d52..efc083d 100644 --- a/src/components/quick-filters/template.njk +++ b/src/components/quick-filters/template.njk @@ -1,19 +1,17 @@ -