From 6e94aeebe61efd97c6daabf6d02e05a8f71377ae Mon Sep 17 00:00:00 2001 From: EdwardScull Date: Fri, 21 Jun 2024 12:43:49 +0100 Subject: [PATCH 1/4] timeline component --- docs/assets/css/app.scss | 22 ++--- docs/components/timeline.md | 19 ++++ docs/examples/timeline/timeline-active.njk | 27 ++++++ docs/examples/timeline/timeline-inactive.njk | 31 +++++++ src/all.scss | 11 ++- src/components/timeline/_timeline.scss | 97 ++++++++++++++++++++ src/components/timeline/macro.njk | 3 + src/components/timeline/timeline.njk | 31 +++++++ 8 files changed, 225 insertions(+), 16 deletions(-) create mode 100644 docs/components/timeline.md create mode 100644 docs/examples/timeline/timeline-active.njk create mode 100644 docs/examples/timeline/timeline-inactive.njk create mode 100644 src/components/timeline/_timeline.scss create mode 100644 src/components/timeline/macro.njk create mode 100644 src/components/timeline/timeline.njk diff --git a/docs/assets/css/app.scss b/docs/assets/css/app.scss index 9e630e6..4a539ad 100644 --- a/docs/assets/css/app.scss +++ b/docs/assets/css/app.scss @@ -1,24 +1,24 @@ // Import all of the NHS.UK frontend core styles -@import "node_modules/nhsuk-frontend/packages/core/all.scss"; +@import "node_modules/nhsuk-frontend/packages/core/all"; // Import specific components that we need from nhsuk-frontend -@import "node_modules/nhsuk-frontend/packages/components/skip-link/skip-link.scss"; -@import "node_modules/nhsuk-frontend/packages/components/header/header.scss"; -@import "node_modules/nhsuk-frontend/packages/components/hero/hero.scss"; -@import "node_modules/nhsuk-frontend/packages/components/tabs/tabs.scss"; -@import "node_modules/nhsuk-frontend/packages/components/breadcrumb/breadcrumb.scss"; +@import "node_modules/nhsuk-frontend/packages/components/breadcrumb/breadcrumb"; +@import "node_modules/nhsuk-frontend/packages/components/skip-link/skip-link"; +@import "node_modules/nhsuk-frontend/packages/components/header/header"; +@import "node_modules/nhsuk-frontend/packages/components/hero/hero"; +@import "node_modules/nhsuk-frontend/packages/components/tabs/tabs"; @import "node_modules/prismjs/themes/prism"; // Import all styles from the NHS App frontend library -@import "src/all.scss"; +@import "src/all"; // Import all styles specific for the design system docs @import "docs/assets/css/components/side-navigation"; -@import "docs/assets/css/tabs.scss"; -@import "docs/assets/css/content.scss"; -@import "docs/assets/css/example.scss"; -@import "docs/assets/css/utilities.scss"; +@import "docs/assets/css/tabs"; +@import "docs/assets/css/content"; +@import "docs/assets/css/example"; +@import "docs/assets/css/utilities"; // Add correct spacing around code highlighter and content pre { diff --git a/docs/components/timeline.md b/docs/components/timeline.md new file mode 100644 index 0000000..78d6754 --- /dev/null +++ b/docs/components/timeline.md @@ -0,0 +1,19 @@ +--- +layout: layouts/component.njk +title: Timeline +description: Timeiline description to be added here +tags: + - component +--- + +## When to use + +[insert when to use content here] + +## How to use + +[insert how to use content here] + +## Accessibility + +[insert accessibility content here] diff --git a/docs/examples/timeline/timeline-active.njk b/docs/examples/timeline/timeline-active.njk new file mode 100644 index 0000000..3f5240d --- /dev/null +++ b/docs/examples/timeline/timeline-active.njk @@ -0,0 +1,27 @@ +--- +layout: layouts/example.njk +title: Timeline active +figmaLink: [insert link to Figma file here] +vueLink: [insert link to Vue component library here] +--- + +{% from "timeline/macro.njk" import timeline %} + +{{ timeline({ + items: [ + { + headingText: "Date referred", + isPastItem: true, + text: "8 June 2024" + }, + { + headingText: "Current status", + active: true, + text: "Waiting for treatment" + }, + { + headingText: "Estimated treatment start date", + text: "September 2024" + } + ] +}) }} \ No newline at end of file diff --git a/docs/examples/timeline/timeline-inactive.njk b/docs/examples/timeline/timeline-inactive.njk new file mode 100644 index 0000000..ca92519 --- /dev/null +++ b/docs/examples/timeline/timeline-inactive.njk @@ -0,0 +1,31 @@ +--- +layout: layouts/example.njk +title: Timeline active +figmaLink: [insert link to Figma file here] +vueLink: [insert link to Vue component library here] +--- + +{% from "timeline/macro.njk" import timeline %} + +{{ timeline({ + items: [ + { + headingText: "Request medication" + }, + { + headingText: "GP Approval Process", + html: " +

Awaiting approval

+

Rejected

+ " + }, + { + headingText: "Pharmacy processing", + html: " +

Pharmacy processing prescription

+

Past prescription is ready to collect

+

Ready to collect from the pharmacy

+ " + } + ] +}) }} \ No newline at end of file diff --git a/src/all.scss b/src/all.scss index 8a106c5..831c04f 100644 --- a/src/all.scss +++ b/src/all.scss @@ -1,10 +1,11 @@ -@import "node_modules/nhsuk-frontend/packages/core/tools/all.scss"; -@import "node_modules/nhsuk-frontend/packages/core/settings/all.scss"; +@import "node_modules/nhsuk-frontend/packages/core/tools/all"; +@import "node_modules/nhsuk-frontend/packages/core/settings/all"; // styles @import "styles/typography"; // components -@import "./components/card/card.scss"; -@import "./components/tag/tag.scss"; -@import "./components/badge/badge"; +@import "components/badge/badge"; +@import "components/card/card"; +@import "components/tag/tag"; +@import "components/timeline/timeline"; diff --git a/src/components/timeline/_timeline.scss b/src/components/timeline/_timeline.scss new file mode 100644 index 0000000..053282f --- /dev/null +++ b/src/components/timeline/_timeline.scss @@ -0,0 +1,97 @@ +/* ========================================================================== + #TIMELINE + ========================================================================== */ + +$timeline-badge-size-mobile: 16px; +$timeline-badge-size-tablet: 20px; +$timeline-badge-small-size-mobile: 12px; +$timeline-badge-small-size-tablet: 16px; + +$timeline-border-width: 2px; + +.nhsapp-timeline { + @include nhsuk-responsive-margin(5, "bottom"); + @include nhsuk-responsive-padding(2, "top"); + + list-style: none; + padding: 0; + + &__item { + @include nhsuk-responsive-padding(5, "bottom"); + + display: flex; + margin-bottom: 0; + margin-left: 12px; + margin-top: -6px; + position: relative; + + &:last-child { + padding: 0; + + &:before { + border: none; + } + } + + &:before { + border-left: $timeline-border-width solid $color_nhsuk-grey-3; + bottom: 0; + content: ""; + display: block; + left: -$timeline-border-width; + position: absolute; + top: nhsuk-spacing(2); + width: $timeline-border-width; + } + + &--past { + &:before { + border-color: $color_nhsuk-blue; + } + } + } + + &__badge { + flex-shrink: 0; + height: $timeline-badge-size-mobile; + margin-left: - calc(($timeline-badge-size-mobile / 2) + ($timeline-border-width / 2)); + margin-right: nhsuk-spacing(4); + margin-top: 4px; + width: $timeline-badge-size-mobile; + z-index: 1; + + @include mq($from: tablet) { + height: $timeline-badge-size-tablet; + margin-left: - calc(($timeline-badge-size-tablet / 2) + ($timeline-border-width / 2)); + margin-top: 3px; + width: $timeline-badge-size-tablet; + } + + &--small { + height: $timeline-badge-small-size-mobile; + margin-left: - calc(($timeline-badge-small-size-mobile / 2) + ($timeline-border-width / 2)); + margin-right: 26px; + margin-top: 6px; + width: $timeline-badge-small-size-mobile; + + @include mq($from: tablet) { + height: $timeline-badge-small-size-tablet; + margin-left: - calc(($timeline-badge-small-size-tablet / 2) + ($timeline-border-width / 2)); + margin-top: 5px; + width: $timeline-badge-small-size-tablet; + } + } + } + + &__header { + @include nhsuk-typography-responsive(19); + font-weight: normal; + margin-bottom: 0; + } + + &__description { + @include nhsuk-typography-responsive(16); + margin-bottom: 0; + padding-top: 0; + } +} diff --git a/src/components/timeline/macro.njk b/src/components/timeline/macro.njk new file mode 100644 index 0000000..cca090b --- /dev/null +++ b/src/components/timeline/macro.njk @@ -0,0 +1,3 @@ +{% macro timeline(params) %} + {%- include "./timeline.njk" -%} +{% endmacro %} diff --git a/src/components/timeline/timeline.njk b/src/components/timeline/timeline.njk new file mode 100644 index 0000000..04bbedb --- /dev/null +++ b/src/components/timeline/timeline.njk @@ -0,0 +1,31 @@ +{% macro _timelineItem(params, item) %} + {% set headingLevel = params.headingLevel if params.headingLevel else 3 %} + {% set headingBold = 'nhsuk-u-font-weight-bold' if item.active else '' %} + {% set isPastItem = 'nhsapp-timeline__item--past' if item.isPastItem else '' %} + +
  • + {% if item.active or item.isPastItem %} + + {% else %} + + {% endif %} +
    + {{ item.headingText }} + {% if item.html %} + {{ item.html | safe | trim }} + {% elif item.text %} +

    {{ item.text }}

    + {% endif %} +
    +
  • +{% endmacro %} + +
      + {% for item in params.items %} + {% if item %}{{ _timelineItem(params, item) }}{% endif %} + {% endfor %} +
    \ No newline at end of file From abe6dbb663aa3c8ee821835169abb14a9578996f Mon Sep 17 00:00:00 2001 From: EdwardScull Date: Tue, 25 Jun 2024 17:18:48 +0100 Subject: [PATCH 2/4] PR comments --- src/components/timeline/_timeline.scss | 71 +++++++++++++++----------- src/components/timeline/timeline.njk | 6 +-- 2 files changed, 44 insertions(+), 33 deletions(-) diff --git a/src/components/timeline/_timeline.scss b/src/components/timeline/_timeline.scss index 053282f..095af2d 100644 --- a/src/components/timeline/_timeline.scss +++ b/src/components/timeline/_timeline.scss @@ -1,14 +1,46 @@ -/* ========================================================================== - #TIMELINE - ========================================================================== */ - $timeline-badge-size-mobile: 16px; -$timeline-badge-size-tablet: 20px; $timeline-badge-small-size-mobile: 12px; -$timeline-badge-small-size-tablet: 16px; - $timeline-border-width: 2px; +@function dot-size($size) { + @if $size == "default" { + @return $timeline-badge-size-mobile; + } @else if $size == "small" { + @return $timeline-badge-small-size-mobile; + } +} + +@function dot-ml($size) { + @return - calc(($size / 2) + ($timeline-border-width / 2)); +} + +@function dot-mt-tablet($margin) { + @return $margin - 1px; +} + +@mixin nhsapp-timeline-badge($size) { + $mt: 4px; + $mt-small: 6px; + + height: dot-size($size); + width: dot-size($size); + + margin-left: dot-ml(dot-size($size)); + margin-top: if($size == "default", $mt, $mt-small); + margin-right: if($size == "default", nhsuk-spacing(4), nhsuk-spacing(4) + 2px); + + @include mq($from: tablet) { + $tablet: dot-size($size) + 4px; + + @debug $tablet; + + height: $tablet; + margin-left: dot-ml($tablet); + margin-top: if($size == "default", dot-mt-tablet($mt), dot-mt-tablet($mt-small)); + width: $tablet; + } +} + .nhsapp-timeline { @include nhsuk-responsive-margin(5, "bottom"); @include nhsuk-responsive-padding(2, "top"); @@ -53,33 +85,12 @@ $timeline-border-width: 2px; &__badge { flex-shrink: 0; - height: $timeline-badge-size-mobile; - margin-left: - calc(($timeline-badge-size-mobile / 2) + ($timeline-border-width / 2)); - margin-right: nhsuk-spacing(4); - margin-top: 4px; - width: $timeline-badge-size-mobile; z-index: 1; - @include mq($from: tablet) { - height: $timeline-badge-size-tablet; - margin-left: - calc(($timeline-badge-size-tablet / 2) + ($timeline-border-width / 2)); - margin-top: 3px; - width: $timeline-badge-size-tablet; - } + @include nhsapp-timeline-badge("default"); &--small { - height: $timeline-badge-small-size-mobile; - margin-left: - calc(($timeline-badge-small-size-mobile / 2) + ($timeline-border-width / 2)); - margin-right: 26px; - margin-top: 6px; - width: $timeline-badge-small-size-mobile; - - @include mq($from: tablet) { - height: $timeline-badge-small-size-tablet; - margin-left: - calc(($timeline-badge-small-size-tablet / 2) + ($timeline-border-width / 2)); - margin-top: 5px; - width: $timeline-badge-small-size-tablet; - } + @include nhsapp-timeline-badge("small"); } } diff --git a/src/components/timeline/timeline.njk b/src/components/timeline/timeline.njk index 04bbedb..7678adc 100644 --- a/src/components/timeline/timeline.njk +++ b/src/components/timeline/timeline.njk @@ -5,12 +5,12 @@
  • {% if item.active or item.isPastItem %} -
    From 177f54394ff27fb8609d801876b5c2650e1ccdd6 Mon Sep 17 00:00:00 2001 From: EdwardScull Date: Wed, 26 Jun 2024 16:12:20 +0100 Subject: [PATCH 3/4] add draft guidance --- docs/components/timeline.md | 58 ++++++++++++++++++-- docs/examples/timeline/timeline-active.njk | 2 +- docs/examples/timeline/timeline-inactive.njk | 2 +- 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/docs/components/timeline.md b/docs/components/timeline.md index 78d6754..adfdc7f 100644 --- a/docs/components/timeline.md +++ b/docs/components/timeline.md @@ -1,19 +1,69 @@ --- layout: layouts/component.njk title: Timeline -description: Timeiline description to be added here +description: Use timelines to help people understand a process and what will happen next. tags: - component --- ## When to use -[insert when to use content here] +Use timelines to show users: + +- what has happened so far +- the point they are currently at +- what will be coming next + +Timelines can work well on: + +- confirmation pages that come after a user has taken an action or submitted a request +- pages that users visit to check on progress + +## When not to use + +Do not use timelines to give lots of detailed information about every stage of a process. Instead, think about how you can give this information to users in context, at the relevant points in their journey. Timelines are meant to help users understand the broad steps of a process, rather than the finer details. ## How to use -[insert how to use content here] +In a timeline you can use nodes (dots), lines and text to explain processes and timings. + +### Nodes + +Nodes can be: + +- white with a grey outline (a smaller dot) +- blue (a larger dot) + +Use blue nodes to show that a step is already completed. + +If you’re using a timeline as a progress indicator, to show users the current status and what is coming next, use blue nodes to do this. But if your timeline is a static list outlining the points in a process in general, every node can be left white. + +{% example "timeline/timeline-active.njk" %} + +### Lines + +Lines between two blue nodes are coloured blue. Otherwise, lines are left grey. + +We would like to better understand whether users associate the length of a line between two nodes with the amount of time that stage will take. You may want to standardise the length of lines between nodes, or test what users understand about timings if you do include differing lengths. + +{% example "timeline/timeline-inactive.njk" %} + +### Text + +Each node should have an accompanying heading that describes which step the process it represents. + +Below each heading, use body text to give further details about that step. This could include a date or a short description. ## Accessibility -[insert accessibility content here] +We want to do further research to understand how screen reader users find timelines, and how much timelines help them to get their bearings. + +## Research + +Our user research has found that in general, users: + +- find timelines helpful for getting their bearings during a process +- are familiar with timelines from other apps and websites they use +- find it helpful that timelines give a visual representation of the process + +Some research suggests that users expect timelines to be dynamic, updating as they make progress. Bear in mind that static timelines may not always meet user expectations. diff --git a/docs/examples/timeline/timeline-active.njk b/docs/examples/timeline/timeline-active.njk index 3f5240d..ce94fb8 100644 --- a/docs/examples/timeline/timeline-active.njk +++ b/docs/examples/timeline/timeline-active.njk @@ -24,4 +24,4 @@ vueLink: [insert link to Vue component library here] text: "September 2024" } ] -}) }} \ No newline at end of file +}) }} diff --git a/docs/examples/timeline/timeline-inactive.njk b/docs/examples/timeline/timeline-inactive.njk index ca92519..2c29bb8 100644 --- a/docs/examples/timeline/timeline-inactive.njk +++ b/docs/examples/timeline/timeline-inactive.njk @@ -28,4 +28,4 @@ vueLink: [insert link to Vue component library here] " } ] -}) }} \ No newline at end of file +}) }} From 4a98d54887d918bffaec44a7b345e682507be18d Mon Sep 17 00:00:00 2001 From: Dave Hunter Date: Mon, 8 Jul 2024 09:19:34 +0100 Subject: [PATCH 4/4] update badge guidance and examples --- docs/components/timeline.md | 23 +++++--------------- docs/examples/timeline/timeline-inactive.njk | 17 ++++----------- 2 files changed, 10 insertions(+), 30 deletions(-) diff --git a/docs/components/timeline.md b/docs/components/timeline.md index adfdc7f..4d99502 100644 --- a/docs/components/timeline.md +++ b/docs/components/timeline.md @@ -6,6 +6,8 @@ tags: - component --- +{% example "timeline/timeline-inactive.njk" %} + ## When to use Use timelines to show users: @@ -14,11 +16,6 @@ Use timelines to show users: - the point they are currently at - what will be coming next -Timelines can work well on: - -- confirmation pages that come after a user has taken an action or submitted a request -- pages that users visit to check on progress - ## When not to use Do not use timelines to give lots of detailed information about every stage of a process. Instead, think about how you can give this information to users in context, at the relevant points in their journey. Timelines are meant to help users understand the broad steps of a process, rather than the finer details. @@ -27,6 +24,8 @@ Do not use timelines to give lots of detailed information about every stage of a In a timeline you can use nodes (dots), lines and text to explain processes and timings. +{% example "timeline/timeline-active.njk" %} + ### Nodes Nodes can be: @@ -36,18 +35,6 @@ Nodes can be: Use blue nodes to show that a step is already completed. -If you’re using a timeline as a progress indicator, to show users the current status and what is coming next, use blue nodes to do this. But if your timeline is a static list outlining the points in a process in general, every node can be left white. - -{% example "timeline/timeline-active.njk" %} - -### Lines - -Lines between two blue nodes are coloured blue. Otherwise, lines are left grey. - -We would like to better understand whether users associate the length of a line between two nodes with the amount of time that stage will take. You may want to standardise the length of lines between nodes, or test what users understand about timings if you do include differing lengths. - -{% example "timeline/timeline-inactive.njk" %} - ### Text Each node should have an accompanying heading that describes which step the process it represents. @@ -67,3 +54,5 @@ Our user research has found that in general, users: - find it helpful that timelines give a visual representation of the process Some research suggests that users expect timelines to be dynamic, updating as they make progress. Bear in mind that static timelines may not always meet user expectations. + +We would like to better understand whether users associate the length of a line between two nodes with the amount of time that stage will take. You may want to standardise the length of lines between nodes, or test what users understand about timings if you do include differing lengths. diff --git a/docs/examples/timeline/timeline-inactive.njk b/docs/examples/timeline/timeline-inactive.njk index 2c29bb8..351a01c 100644 --- a/docs/examples/timeline/timeline-inactive.njk +++ b/docs/examples/timeline/timeline-inactive.njk @@ -10,22 +10,13 @@ vueLink: [insert link to Vue component library here] {{ timeline({ items: [ { - headingText: "Request medication" + headingText: "Await approval", + text: "The request will either be approved or rejected. If rejected please contact your Healthcare Professional.", + active: true }, { headingText: "GP Approval Process", - html: " -

    Awaiting approval

    -

    Rejected

    - " - }, - { - headingText: "Pharmacy processing", - html: " -

    Pharmacy processing prescription

    -

    Past prescription is ready to collect

    -

    Ready to collect from the pharmacy

    - " + text: "Once approved, it can take 3 to 5 working days for a nominated pharmacy to prepare your prescription." } ] }) }}