├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ ├── documentation.md │ ├── feature_request.md │ ├── internal-story.md │ └── propose.md ├── .gitignore ├── .pa11yci.json ├── LICENSE ├── README.md ├── app ├── assets │ ├── docs │ │ ├── english_cookie_content.md │ │ └── welsh_cookie_content.md │ ├── images │ │ ├── add-another-thing │ │ │ ├── add-another-multi-page-change-remove.svg │ │ │ ├── add-another-multi-page.svg │ │ │ ├── add-another-single-page-change-remove.svg │ │ │ ├── add-another-single-page.svg │ │ │ └── order-pizza │ │ │ │ ├── _size.png │ │ │ │ ├── _toppings.png │ │ │ │ └── _who.png │ │ ├── app-header-crest.svg │ │ ├── app-icon-pointer.svg │ │ ├── calendar-date-picker.gif │ │ ├── cookies │ │ │ ├── cookies-accept-reject.png │ │ │ ├── cookies-accept.png │ │ │ ├── cookies-banner.png │ │ │ ├── cookies-footer.png │ │ │ └── cookies-reject.png │ │ ├── daniella-team.jpg │ │ ├── downtime-warning.png │ │ ├── dwp-apple-touch-icon-120x120.png │ │ ├── dwp-apple-touch-icon-152x152.png │ │ ├── dwp-apple-touch-icon-60x60.png │ │ ├── dwp-apple-touch-icon-76x76.png │ │ ├── favicon.ico │ │ ├── find-info-from-doc-illustration.sketch │ │ ├── helen-team.png │ │ ├── information-from-document.png │ │ ├── jon-team.png │ │ ├── key-information.png │ │ ├── martin-team.png │ │ ├── mikey-team.jpg │ │ ├── mitz-team.jpg │ │ ├── simone-team.jpg │ │ ├── structured-answers.gif │ │ ├── task-list.png │ │ └── time-out-modal.png │ ├── javascript │ │ ├── application.js │ │ ├── back-to-top.js │ │ ├── cookies-consent.js │ │ ├── copy-code-button.js │ │ ├── example.js │ │ ├── mobile-navigation.js │ │ ├── tabs.js │ │ ├── timeout-warning.js │ │ └── vendor │ │ │ ├── classList.js │ │ │ ├── common.js │ │ │ └── dialog-polyfill.js │ └── sass │ │ ├── _app-pane.scss │ │ ├── _app-phase-banner.scss │ │ ├── _back-to-top.scss │ │ ├── _contact-panel.scss │ │ ├── _cookie-banner.scss │ │ ├── _example.scss │ │ ├── _header.scss │ │ ├── _highlight.scss │ │ ├── _layout.scss │ │ ├── _masthead.scss │ │ ├── _mobile-navigation.scss │ │ ├── _navigation.scss │ │ ├── _sub-navigation.scss │ │ ├── _tabs.scss │ │ ├── _timeout-warning.scss │ │ ├── _toggle-to-welsh.scss │ │ ├── application-ie8.scss │ │ ├── application.scss │ │ └── vendor │ │ └── dialog-polyfill.0.5.0.css ├── middleware │ ├── accessibility.js │ ├── cookies │ │ ├── cookieDetails.js │ │ ├── cookiePolicy.js │ │ └── cookiesConsent.js │ ├── errorHandler.js │ ├── sitemap.js │ └── urlPartials.js ├── routes │ ├── auto.js │ ├── index.js │ └── redirects.js ├── utils │ ├── content-loader.js │ ├── file-helper.js │ ├── navigation-data-loader.js │ └── regexes.js └── views │ ├── _layouts │ ├── base.html │ ├── code.html │ ├── full-width.html │ └── sidebar-width.html │ ├── _partials │ ├── _accessibility.njk │ ├── _back-to-top.njk │ ├── _component-index.njk │ ├── _component-table.njk │ ├── _contact-panel.njk │ ├── _contribute-index.njk │ ├── _cookie-banner.njk │ ├── _cookie-details.njk │ ├── _cookie-policy.njk │ ├── _footer.njk │ ├── _header.html │ ├── _macros │ │ ├── backlog │ │ │ ├── macro.njk │ │ │ └── template.njk │ │ ├── example │ │ │ ├── README.md │ │ │ ├── macro.njk │ │ │ └── template.njk │ │ ├── mobile-navigation │ │ │ ├── macro.njk │ │ │ └── template.njk │ │ ├── navigation │ │ │ ├── macro.njk │ │ │ └── template.njk │ │ └── sub-navigation │ │ │ ├── macro.njk │ │ │ └── template.njk │ ├── _page-not-found.njk │ ├── _pattern-index.njk │ ├── _pattern-table.njk │ ├── _sitemap.njk │ └── scripts.html │ ├── community │ ├── README.md │ ├── backlog │ │ ├── README.md │ │ └── index.html │ ├── contribute │ │ ├── README.md │ │ └── index.html │ ├── index.html │ ├── latest-updates │ │ ├── README.md │ │ └── index.html │ ├── roadmap │ │ ├── README.md │ │ └── index.html │ └── team │ │ ├── README.md │ │ ├── _team-daniella.njk │ │ ├── _team-helen.njk │ │ ├── _team-jon.njk │ │ ├── _team-martin.njk │ │ ├── _team-mitz.njk │ │ ├── _team-simone.njk │ │ └── index.html │ ├── components │ ├── README.md │ ├── hint-text │ │ ├── README.md.njk │ │ ├── examples │ │ │ └── default │ │ │ │ ├── index.html │ │ │ │ ├── styles.css │ │ │ │ └── template.html │ │ └── index.html │ ├── index.html │ ├── internal-services-footer │ │ ├── README.md.njk │ │ ├── examples │ │ │ ├── default │ │ │ │ ├── index.html │ │ │ │ └── template.html │ │ │ ├── meta-links │ │ │ │ ├── index.html │ │ │ │ └── template.html │ │ │ └── nav-and-links │ │ │ │ ├── index.html │ │ │ │ └── template.html │ │ └── index.html │ ├── internal-services-header │ │ ├── README.md.njk │ │ ├── examples │ │ │ ├── default │ │ │ │ ├── index.html │ │ │ │ ├── styles.css │ │ │ │ └── template.html │ │ │ └── signin │ │ │ │ ├── index.html │ │ │ │ ├── styles.css │ │ │ │ └── template.html │ │ └── index.html │ ├── key-details-bar │ │ ├── README.md.njk │ │ ├── examples │ │ │ ├── default │ │ │ │ ├── index.html │ │ │ │ ├── styles.css │ │ │ │ └── template.html │ │ │ └── notdo │ │ │ │ ├── index.html │ │ │ │ └── template.html │ │ └── index.html │ └── timeline │ │ ├── README.md.njk │ │ ├── examples │ │ └── default │ │ │ ├── index.html │ │ │ ├── styles.css │ │ │ └── template.html │ │ └── index.html │ ├── get-started │ ├── README.md │ ├── html-and-css │ │ ├── README.md │ │ └── index.html │ ├── index.html │ └── npm │ │ ├── README.md │ │ └── index.html │ ├── index.html │ └── patterns │ ├── README.md │ ├── add-another-thing │ ├── README.md.njk │ ├── example │ │ ├── README.md.njk │ │ └── index.html │ └── index.html │ ├── index.html │ ├── make-a-declaration │ ├── README.md.njk │ ├── examples │ │ └── default │ │ │ ├── index.html │ │ │ └── template.html │ └── index.html │ ├── manage-a-session-timeout │ ├── README.md.njk │ ├── examples │ │ ├── default │ │ │ ├── index.html │ │ │ └── template.html │ │ ├── notsignedin │ │ │ ├── index.html │ │ │ └── template.html │ │ ├── signedin │ │ │ ├── index.html │ │ │ └── template.html │ │ ├── timedout-nojs │ │ │ ├── index.html │ │ │ └── template.html │ │ ├── timedout-notsignedin │ │ │ ├── index.html │ │ │ └── template.html │ │ └── timedout-signedin │ │ │ ├── index.html │ │ │ └── template.html │ ├── index.html │ ├── macro.njk │ ├── template.html │ └── timed-out.html │ ├── retired-patterns │ ├── README.md.njk │ ├── consent-to-cookies │ │ ├── README.md.njk │ │ └── index.html │ └── index.html │ └── toggle-to-welsh │ ├── README.md.njk │ ├── examples │ ├── default │ │ ├── index.html │ │ └── template.html │ └── start-page │ │ ├── index.html │ │ └── template.html │ └── index.html ├── config ├── content │ └── backlog-page.json └── navigation-data.json ├── gulp ├── clean.js ├── compile-app-js.js ├── copy-assets.js ├── sass.js ├── server.js └── watch.js ├── gulpfile.js ├── package-lock.json ├── package.json └── server.js /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "🐛 Bug report" 3 | about: Report a bug or regression 4 | title: '' 5 | labels: "\U0001F41B bug, awaiting triage" 6 | assignees: '' 7 | 8 | --- 9 | 10 | 15 | 16 | ## Describe the issue 17 | 18 | 19 | ## Steps to reproduce the issue 20 | 21 | 22 | ## Actual vs expected behaviour 23 | 24 | 25 | ## Environment (where applicable) 26 | 27 | 28 | - Operating system: 29 | - Browser: 30 | - Browser version: -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | 2 | blank_issues_enabled: true 3 | contact_links: 4 | - name: Get in touch another way 5 | url: https://design-system.dwp.gov.uk/get-in-touch.html 6 | about: Find out how to get in touch via email or Slack -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "📖 Documentation" 3 | about: Add new documentation, or report missing, incorrect or unclear documentation 4 | title: '' 5 | labels: "documentation, awaiting triage" 6 | assignees: '' 7 | 8 | --- 9 | 10 | 17 | 18 | ## Related documentation 19 | 20 | 21 | ## Suggestion 22 | 23 | 24 | ## Evidence (where applicable) 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "✨ Feature request" 3 | about: Suggest a new feature or idea 4 | title: '' 5 | labels: "feature request, awaiting triage" 6 | assignees: '' 7 | 8 | --- 9 | 10 | 19 | 20 | ## Context 21 | 22 | 23 | ## Alternatives 24 | 25 | 26 | ## Additional information (if applicable) 27 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/internal-story.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Internal story template" 3 | about: For internal use only 4 | title: '' 5 | labels: "awaiting triage" 6 | assignees: '' 7 | 8 | --- 9 | 10 | 15 | 16 | ## What 17 | 18 | ## Why 19 | 20 | ## Done when 21 | 22 | - [ ] Thing to do 23 | 24 | ## Outcomes 25 | 26 | ## Who needs to know about this 27 | 28 | ## Related stories 29 | 30 | ## Anything else 31 | 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/propose.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | ## What 8 | > Give a brief description of the style, component or pattern you want to propose. 9 | 10 | ## Why 11 | > Explain why you think this should be added to the DWP Design System. 12 | > 13 | > - What evidence do you have that it's needed by multiple services across DWP? 14 | > - What evidence do you have that it meets the needs of the users of those services? 15 | > - Have you checked that it doesn't already exist in the DWP Design System? 16 | 17 | ## Anything else 18 | > Include links to any examples, research or code to support your proposal, if available. 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | sass-cache 3 | .DS_Store 4 | public/ 5 | .vscode/ 6 | settings.json 7 | npm-debug.log 8 | pa11y-ci-report 9 | -------------------------------------------------------------------------------- /.pa11yci.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaults": { 3 | "ignore": [ 4 | "color-contrast" 5 | ], 6 | "timeout": 10000, 7 | "reporters": [ 8 | "cli", 9 | [ 10 | "./node_modules/pa11y-ci-reporter-html", 11 | { 12 | "destination": "./pa11y-ci-report", 13 | "includeZeroIssues": true 14 | } 15 | ] 16 | ], 17 | "standard": "WCAG2AA", 18 | "runners": [ 19 | "htmlcs", 20 | "axe" 21 | ] 22 | }, 23 | "urls": [ 24 | "http://localhost:3000/", 25 | "http://localhost:3000/get-started", 26 | "http://localhost:3000/get-started/for-designers", 27 | "http://localhost:3000/community", 28 | "http://localhost:3000/community/roadmap", 29 | "http://localhost:3000/community/contribute", 30 | "http://localhost:3000/community/backlog", 31 | "http://localhost:3000/community/latest-updates", 32 | "http://localhost:3000/community/team", 33 | "http://localhost:3000/patterns", 34 | "http://localhost:3000/patterns/retired-patterns", 35 | "http://localhost:3000/patterns/retired-patterns/consent-to-cookies", 36 | "http://localhost:3000/patterns/add-another-thing", 37 | "http://localhost:3000/patterns/manage-a-session-timeout", 38 | "http://localhost:3000/patterns/manage-a-session-timeout/examples/default", 39 | "http://localhost:3000/patterns/manage-a-session-timeout/examples/signedin", 40 | "http://localhost:3000/patterns/manage-a-session-timeout/examples/timedout-signedin", 41 | "http://localhost:3000/patterns/manage-a-session-timeout/examples/notsignedin", 42 | "http://localhost:3000/patterns/manage-a-session-timeout/examples/timedout-notsignedin", 43 | "http://localhost:3000/patterns/manage-a-session-timeout/examples/timedout-nojs", 44 | "http://localhost:3000/patterns/make-a-declaration", 45 | "http://localhost:3000/patterns/make-a-declaration/examples/default", 46 | "http://localhost:3000/patterns/toggle-to-welsh", 47 | "http://localhost:3000/patterns/toggle-to-welsh/examples/default", 48 | "http://localhost:3000/patterns/toggle-to-welsh/examples/start-page", 49 | "http://localhost:3000/components/hint-text", 50 | "http://localhost:3000/components/timeline", 51 | "http://localhost:3000/components/timeline/examples/default", 52 | "http://localhost:3000/components/internal-services-header", 53 | "http://localhost:3000/components/internal-services-header/examples/default", 54 | "http://localhost:3000/components/internal-services-header/examples/signin", 55 | "http://localhost:3000/components/key-details-bar", 56 | "http://localhost:3000/components/key-details-bar/examples/default", 57 | "http://localhost:3000/cookie-details", 58 | "http://localhost:3000/cookie-policy" 59 | ] 60 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 DWP (The Department for Work and Pensions) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Design System 2 | 3 | One place for service teams to find and share the styles, components and patterns for designing DWP services. 4 | 5 | ## Get started 6 | 7 | `npm install && npm start` 8 | 9 | ## Accessibility 10 | 11 | The site uses `pa11y-ci` with `axe-core` and `htmlcs` (default) as runners. To run a11y tests: 12 | `npm run reports` 13 | 14 | This generates an HTML report for every website url in the `pa11y-ci-report` folder. -------------------------------------------------------------------------------- /app/assets/docs/english_cookie_content.md: -------------------------------------------------------------------------------- 1 | [Screen 1] 2 | 3 | How we use cookies 4 | 5 | A cookie is a small file which is stored on your device for a short time to make this service work. 6 | 7 | We use cookies that are: 8 | • Essential for the service to work, like remembering your answers to certain questions 9 | • Optional and will not stop the service from working, but will give us information to help us make it better 10 | 11 | We will not: 12 | • Use any essential cookies until you use the service 13 | • Use any optional cookies unless you tell us we can 14 | • Be able to identify you through using cookies 15 | 16 | Optional cookie settings 17 | 18 | Analytics cookies 19 | 20 | We use Google Analytics to get information about how you use this service and help us make it better. 21 | 22 | Can we use cookies to help us improve the service? 23 | Yes 24 | No 25 | 26 | Save and continue 27 | 28 | Find out more about cookies on this service 29 | 30 | 31 | [Banner 1] 32 | 33 | Can we use cookies in our services? 34 | 35 | We’d like to use analytics cookies to collect information about how you use our services. This helps us to make them better. 36 | You can read more about our cookies before you decide. 37 | 38 | Yes, I’m OK with analytics cookies  39 | No, do no use analytics cookies 40 | 41 | 42 | [Banner 2] 43 | 44 | ACCEPTED 45 | You’ve accepted analytics cookies. You can  change your cookie settings at any time. 46 | 47 | Hide 48 | 49 | 50 | [Banner 3] 51 | 52 | REJECTED 53 | You’ve rejected analytics cookies. You can  change your cookie settings at any time. 54 | 55 | Hide 56 | 57 | -------------------------------------------------------------------------------- /app/assets/docs/welsh_cookie_content.md: -------------------------------------------------------------------------------- 1 | [Screen 1] 2 | 3 | Sut rydym yn defnyddio cwcis 4 | 5 | Ffeil fach yw cwci sy'n cael ei storio ar eich dyfais am gyfnod byr i wneud i'r gwasanaeth hwn weithio. 6 | 7 | Rydym yn defnyddio cwcis sy’n: 8 | • Hanfodol i'r gwasanaeth weithio, fel cofio'ch atebion i gwestiynau penodol 9 | • Dewisol ac ni fydd yn atal y gwasanaeth rhag gweithio, ond bydd yn rhoi gwybodaeth i ni i'n helpu i'w wella 10 | 11 | Ni fyddwn yn: 12 | • Defnyddio unrhyw gwcis hanfodol hyd nes i chi ddefnyddio'r gwasanaeth 13 | • Defnyddio unrhyw gwcis dewisol oni bai eich bod yn dweud wrthym y gallwn 14 | • Gallu'ch adnabod trwy ddefnyddio cwcis 15 | 16 | Gosodiadau cwci dewisol 17 | 18 | Cwcis dadansoddeg 19 | 20 | Rydyn ni'n defnyddio Google Analytics i gael gwybodaeth am sut rydych yn defnyddio'r gwasanaeth hwn ac yn ein helpu i'w wella. 21 | 22 | A allwn ddefnyddio cwcis i'n helpu i wella'r gwasanaeth? 23 | Gallwch 24 | Na 25 | 26 | Arbed a pharhau 27 | 28 | Darganfyddwch fwy am gwcis ar y gwasanaeth hwn 29 | 30 | 31 | [Banner 1] 32 | 33 | A allwn ddefnyddio cwcis yn ein gwasanaethau? 34 | 35 | Hoffem ddefnyddio cwcis dadansoddeg i gasglu gwybodaeth am sut rydych yn defnyddio ein gwasanaethau. Mae hyn yn ein helpu i'w gwella. 36 | Gallwch ddarllen mwy am ein cwcis cyn i chi benderfynu. 37 | 38 | Ydw, rwy'n iawn gyda chwcis dadansoddeg 39 | Na, peidiwch â defnyddio cwcis dadansoddeg 40 | 41 | 42 | [Banner 2] 43 | 44 | DERBYNIWYD 45 | Rydych wedi derbyn cwcis dadansoddeg. Gallwch newid eich gosodiadau cwci ar unrhyw adeg. 46 | 47 | Cuddio 48 | 49 | 50 | [Banner 3] 51 | 52 | GWRTHODWYD 53 | Rydych wedi gwrthod cwcis dadansoddeg. Gallwch newid eich gosodiadau cwci ar unrhyw adeg. 54 | 55 | Cuddio 56 | -------------------------------------------------------------------------------- /app/assets/images/add-another-thing/order-pizza/_size.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/add-another-thing/order-pizza/_size.png -------------------------------------------------------------------------------- /app/assets/images/add-another-thing/order-pizza/_toppings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/add-another-thing/order-pizza/_toppings.png -------------------------------------------------------------------------------- /app/assets/images/add-another-thing/order-pizza/_who.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/add-another-thing/order-pizza/_who.png -------------------------------------------------------------------------------- /app/assets/images/app-icon-pointer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/assets/images/calendar-date-picker.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/calendar-date-picker.gif -------------------------------------------------------------------------------- /app/assets/images/cookies/cookies-accept-reject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/cookies/cookies-accept-reject.png -------------------------------------------------------------------------------- /app/assets/images/cookies/cookies-accept.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/cookies/cookies-accept.png -------------------------------------------------------------------------------- /app/assets/images/cookies/cookies-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/cookies/cookies-banner.png -------------------------------------------------------------------------------- /app/assets/images/cookies/cookies-footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/cookies/cookies-footer.png -------------------------------------------------------------------------------- /app/assets/images/cookies/cookies-reject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/cookies/cookies-reject.png -------------------------------------------------------------------------------- /app/assets/images/daniella-team.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/daniella-team.jpg -------------------------------------------------------------------------------- /app/assets/images/downtime-warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/downtime-warning.png -------------------------------------------------------------------------------- /app/assets/images/dwp-apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/dwp-apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /app/assets/images/dwp-apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/dwp-apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /app/assets/images/dwp-apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/dwp-apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /app/assets/images/dwp-apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/dwp-apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /app/assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/favicon.ico -------------------------------------------------------------------------------- /app/assets/images/find-info-from-doc-illustration.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/find-info-from-doc-illustration.sketch -------------------------------------------------------------------------------- /app/assets/images/helen-team.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/helen-team.png -------------------------------------------------------------------------------- /app/assets/images/information-from-document.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/information-from-document.png -------------------------------------------------------------------------------- /app/assets/images/jon-team.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/jon-team.png -------------------------------------------------------------------------------- /app/assets/images/key-information.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/key-information.png -------------------------------------------------------------------------------- /app/assets/images/martin-team.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/martin-team.png -------------------------------------------------------------------------------- /app/assets/images/mikey-team.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/mikey-team.jpg -------------------------------------------------------------------------------- /app/assets/images/mitz-team.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/mitz-team.jpg -------------------------------------------------------------------------------- /app/assets/images/simone-team.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/simone-team.jpg -------------------------------------------------------------------------------- /app/assets/images/structured-answers.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/structured-answers.gif -------------------------------------------------------------------------------- /app/assets/images/task-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/task-list.png -------------------------------------------------------------------------------- /app/assets/images/time-out-modal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwp/design-system/5340efdeb36a7189b6ea274c1487a4ff768f6109/app/assets/images/time-out-modal.png -------------------------------------------------------------------------------- /app/assets/javascript/application.js: -------------------------------------------------------------------------------- 1 | import common from './vendor/common'; 2 | import dialogPolyfill from './vendor/dialog-polyfill'; 3 | import BackToTop from './back-to-top'; 4 | import Example from './example'; 5 | import MobileNav from './mobile-navigation'; 6 | import CopyCodeButton from './copy-code-button'; 7 | import Tabs from './tabs'; 8 | import CookiesConsent from './cookies-consent'; 9 | import TimeoutWarning from './timeout-warning'; 10 | 11 | const { nodeListForEach } = common; 12 | 13 | // Initialise example frames 14 | const $examples = document.querySelectorAll('[data-module="app-example-frame"]'); 15 | nodeListForEach($examples, ($example) => { 16 | new Example($example).init(); 17 | }); 18 | 19 | // Register dialog polyfill 20 | const dialog = document.querySelector('.govuk-timeout-warning'); 21 | if (dialog) { 22 | dialogPolyfill.registerDialog(dialog); 23 | } 24 | 25 | // Initialise mobile navigation 26 | new MobileNav().init(); 27 | 28 | // Initialise back to top 29 | const $backToTop = document.querySelector('[data-module="app-back-to-top"]'); 30 | new BackToTop($backToTop).init(); 31 | 32 | document.querySelectorAll('.app-example__copy-code-button').forEach((button) => { 33 | new CopyCodeButton(button).init(); 34 | }); 35 | 36 | document.querySelectorAll('.app-tabs').forEach((tabs) => { 37 | new Tabs(tabs).init(); 38 | }); 39 | 40 | const cookieBanner = document.querySelector('.cookie-banner'); 41 | if (cookieBanner) { 42 | new CookiesConsent(cookieBanner).init(); 43 | } 44 | 45 | const timeoutWarnings = document.querySelectorAll('[data-module="govuk-timeout-warning"]'); 46 | nodeListForEach(timeoutWarnings, (timeoutWarning) => { 47 | new TimeoutWarning(timeoutWarning).init(); 48 | }); 49 | -------------------------------------------------------------------------------- /app/assets/javascript/back-to-top.js: -------------------------------------------------------------------------------- 1 | import 'govuk-frontend/govuk/vendor/polyfills/Function/prototype/bind'; 2 | 3 | function BackToTop($module) { 4 | this.$module = $module; 5 | } 6 | 7 | BackToTop.prototype.init = function () { 8 | if (!this.$module) { 9 | return; 10 | } 11 | 12 | // Check if we can use Intersection Observers 13 | if (!('IntersectionObserver' in window)) { 14 | // If there's no support fallback to regular behaviour 15 | // Since JavaScript is enabled we can remove the default hidden state 16 | return this.$module.classList.remove('app-back-to-top--hidden'); 17 | } 18 | 19 | const $footer = document.querySelector('.app-footer'); 20 | const $subNav = document.querySelector('.app-subnav'); 21 | 22 | // Check if there is anything to observe 23 | if (!$footer || !$subNav) { 24 | return; 25 | } 26 | 27 | let footerIsIntersecting = false; 28 | let subNavIsIntersecting = false; 29 | let subNavIntersectionRatio = 0; 30 | 31 | const observer = new window.IntersectionObserver((entries) => { 32 | // Find the elements we care about from the entries 33 | const footerEntry = entries.find((entry) => entry.target === $footer); 34 | const subNavEntry = entries.find((entry) => entry.target === $subNav); 35 | 36 | // If there is an entry this means the element has changed so lets check if it's intersecting. 37 | if (footerEntry) { 38 | footerIsIntersecting = footerEntry.isIntersecting; 39 | } 40 | if (subNavEntry) { 41 | subNavIsIntersecting = subNavEntry.isIntersecting; 42 | subNavIntersectionRatio = subNavEntry.intersectionRatio; 43 | } 44 | 45 | // If the subnav or the footer not visible then fix the back to top link to follow the user 46 | if (subNavIsIntersecting || footerIsIntersecting) { 47 | this.$module.classList.remove('app-back-to-top--fixed'); 48 | } else { 49 | this.$module.classList.add('app-back-to-top--fixed'); 50 | } 51 | 52 | // If the subnav is visible but you can see it all at once, then a back to top link is likely not as useful. 53 | // We hide the link but make it focusable for screen readers users who might still find it useful. 54 | if (subNavIsIntersecting && subNavIntersectionRatio === 1) { 55 | this.$module.classList.add('app-back-to-top--hidden'); 56 | } else { 57 | this.$module.classList.remove('app-back-to-top--hidden'); 58 | } 59 | }); 60 | 61 | observer.observe($footer); 62 | observer.observe($subNav); 63 | }; 64 | 65 | export default BackToTop; 66 | -------------------------------------------------------------------------------- /app/assets/javascript/cookies-consent.js: -------------------------------------------------------------------------------- 1 | function CookiesConsent($module) { 2 | this.$module = $module; 3 | this.cookieBannerButtonAcceptHide = this.$module.querySelector('.cookie-banner-accept--hide'); 4 | this.cookieBannerButtonRejectHide = this.$module.querySelector('.cookie-banner-reject--hide'); 5 | this.cookieBannerButtonAccept = this.$module.querySelector('.cookie-banner-button--accept'); 6 | this.cookieBannerButtonReject = this.$module.querySelector('.cookie-banner-button--reject'); 7 | this.cookieBannerAccept = this.$module.querySelector('.cookie-banner--accept'); 8 | this.cookieBannerReject = this.$module.querySelector('.cookie-banner--reject'); 9 | this.cookieBannerMain = this.$module.querySelector('.cookie-banner--main'); 10 | this.cookieBanner = document.querySelector('.cookie-banner'); 11 | } 12 | 13 | CookiesConsent.prototype.init = function () { 14 | if (!this.$module) { 15 | return; 16 | } 17 | 18 | if (document.cookie && document.cookie.indexOf('dwp_analytics') !== -1) { 19 | this.hideElement(this.cookieBanner); 20 | } 21 | 22 | if (this.cookieBannerButtonAcceptHide != null) { 23 | this.cookieBannerButtonAcceptHide.addEventListener('click', this.hideConfirmation.bind(this)); 24 | this.cookieBannerButtonRejectHide.addEventListener('click', this.hideConfirmation.bind(this)); 25 | } 26 | if (this.cookieBanner != null) { 27 | this.cookieBannerButtonAccept.addEventListener('click', this.showConfirmation.bind(this)); 28 | this.cookieBannerButtonReject.addEventListener('click', this.showConfirmation.bind(this)); 29 | } 30 | }; 31 | 32 | CookiesConsent.prototype.setCookie = function (type) { 33 | const date = new Date(); 34 | const days = 365; 35 | date.setTime(date.getTime() + 24 * days * 60 * 60 * 1e3); 36 | document.cookie = `dwp_analytics=${ 37 | encodeURIComponent(type) 38 | }; expires=${ 39 | date.toGMTString() 40 | }; path=/`; 41 | }; 42 | 43 | CookiesConsent.prototype.hideElement = function (element) { 44 | if (element) { 45 | element.classList.add('hidden'); 46 | } 47 | }; 48 | 49 | CookiesConsent.prototype.showElement = function (element) { 50 | element.setAttribute('tabindex', -1); 51 | element.classList.remove('hidden'); 52 | }; 53 | 54 | CookiesConsent.prototype.hideConfirmation = function (e) { 55 | e.preventDefault(); 56 | this.hideElement(this.cookieBanner); 57 | }; 58 | 59 | CookiesConsent.prototype.showConfirmation = function (e) { 60 | e.preventDefault(); 61 | const cookieValue = e.target.value; 62 | this.hideElement(this.cookieBannerMain); 63 | if (cookieValue === 'accept') { 64 | this.setCookie('accept'); 65 | this.showElement(this.cookieBannerAccept); 66 | } 67 | if (cookieValue === 'reject') { 68 | this.setCookie('reject'); 69 | this.showElement(this.cookieBannerReject); 70 | } 71 | }; 72 | 73 | export default CookiesConsent; 74 | -------------------------------------------------------------------------------- /app/assets/javascript/copy-code-button.js: -------------------------------------------------------------------------------- 1 | function CopyCodeButton($module) { 2 | this.$module = $module; 3 | } 4 | 5 | CopyCodeButton.prototype.init = function () { 6 | if (!this.$module) { 7 | return; 8 | } 9 | 10 | this.$module.addEventListener('click', () => { 11 | this.$module.textContent = 'Code copied'; 12 | setTimeout(() => { 13 | this.$module.textContent = 'Copy code'; 14 | }, 2000); 15 | const code = document.getElementsByClassName('app-js-visible')[0].querySelector('pre').textContent; 16 | navigator.clipboard.writeText(code); 17 | }); 18 | }; 19 | 20 | export default CopyCodeButton; 21 | -------------------------------------------------------------------------------- /app/assets/javascript/example.js: -------------------------------------------------------------------------------- 1 | import 'govuk-frontend/govuk/vendor/polyfills/Event'; 2 | 3 | function ExamplePage($module) { 4 | this.$module = $module; 5 | } 6 | ExamplePage.prototype.init = function () { 7 | const { $module } = this; 8 | if (!$module) { 9 | return; 10 | } 11 | const $form = $module.querySelector('form[action="/form-handler"]'); 12 | this.preventFormSubmission($form); 13 | }; 14 | ExamplePage.prototype.preventFormSubmission = function ($form) { 15 | // we should only have one form per example 16 | if (!$form) { 17 | return false; 18 | } 19 | $form.addEventListener('submit', (e) => { 20 | e.preventDefault(); 21 | }); 22 | }; 23 | 24 | new ExamplePage(document).init(); 25 | -------------------------------------------------------------------------------- /app/assets/javascript/mobile-navigation.js: -------------------------------------------------------------------------------- 1 | import common from './vendor/common'; 2 | 3 | const { nodeListForEach } = common; 4 | 5 | const navActiveClass = 'app-mobile-nav--active'; 6 | const navTogglerActiveClass = 'app-header-mobile-nav-toggler--active'; 7 | const subNavActiveClass = 'app-mobile-nav__subnav--active'; 8 | const subNavTogglerActiveClass = 'app-mobile-nav__subnav-toggler--active'; 9 | 10 | function MobileNav($module) { 11 | this.$module = $module || document; 12 | this.$nav = this.$module.querySelector('.js-app-mobile-nav'); 13 | this.$navToggler = this.$module.querySelector('.js-app-mobile-nav-toggler'); 14 | } 15 | 16 | MobileNav.prototype.bindUIEvents = function () { 17 | const { $nav } = this; 18 | const { $navToggler } = this; 19 | 20 | if ($navToggler) { 21 | $navToggler.addEventListener('click', (event) => { 22 | if ($nav.classList.contains(navActiveClass)) { 23 | $nav.classList.remove(navActiveClass); 24 | $nav.setAttribute('aria-hidden', 'true'); 25 | 26 | $navToggler.classList.remove(navTogglerActiveClass); 27 | $navToggler.setAttribute('aria-expanded', 'false'); 28 | } else { 29 | $nav.classList.add(navActiveClass); 30 | $nav.setAttribute('aria-hidden', 'false'); 31 | 32 | $navToggler.setAttribute('aria-expanded', 'true'); 33 | $navToggler.classList.add(navTogglerActiveClass); 34 | } 35 | }); 36 | } 37 | 38 | if ($nav) { 39 | $nav.addEventListener('click', (event) => { 40 | const $toggler = event.target; 41 | if (!$toggler.classList.contains('js-mobile-nav-subnav-toggler')) { 42 | return; 43 | } 44 | // The presentational touch area of the toggler is on it's parent. 45 | const $togglerLinkArea = $toggler.parentNode; 46 | 47 | const $nextSubNav = $togglerLinkArea.parentNode.querySelector('.js-app-mobile-nav-subnav'); 48 | 49 | if ($nextSubNav) { 50 | if ($nextSubNav.classList.contains(subNavActiveClass)) { 51 | $nextSubNav.classList.remove(subNavActiveClass); 52 | $togglerLinkArea.classList.remove(subNavTogglerActiveClass); 53 | 54 | $nextSubNav.setAttribute('aria-hidden', 'true'); 55 | $toggler.setAttribute('aria-expanded', 'false'); 56 | } else { 57 | $nextSubNav.classList.add(subNavActiveClass); 58 | $togglerLinkArea.classList.add(subNavTogglerActiveClass); 59 | 60 | $nextSubNav.setAttribute('aria-hidden', 'false'); 61 | $toggler.setAttribute('aria-expanded', 'true'); 62 | } 63 | event.preventDefault(); 64 | } 65 | }); 66 | } 67 | }; 68 | 69 | MobileNav.prototype.includeAria = function () { 70 | if (this.$nav) { 71 | this.$nav.setAttribute('aria-hidden', 'true'); 72 | } 73 | 74 | const { $navToggler } = this; 75 | if (this.$navToggler) { 76 | $navToggler.setAttribute('aria-expanded', 'false'); 77 | } 78 | 79 | const $subNavTogglers = this.$module.querySelectorAll('.js-mobile-nav-subnav-toggler'); 80 | 81 | nodeListForEach($subNavTogglers, ($toggler, index) => { 82 | const $nextSubNav = $toggler.parentNode.parentNode.querySelector('.js-app-mobile-nav-subnav'); 83 | 84 | if ($nextSubNav) { 85 | const navIsOpen = $nextSubNav.classList.contains(subNavActiveClass); 86 | const subNavTogglerId = `js-mobile-nav-subnav-toggler-${index}`; 87 | const nextSubNavId = `js-mobile-nav__subnav-${index}`; 88 | 89 | $nextSubNav.setAttribute('id', nextSubNavId); 90 | $nextSubNav.setAttribute('aria-hidden', navIsOpen ? 'false' : 'true'); 91 | 92 | $toggler.setAttribute('id', subNavTogglerId); 93 | $toggler.setAttribute('aria-expanded', navIsOpen ? 'true' : 'false'); 94 | $toggler.setAttribute('aria-controls', nextSubNavId); 95 | } 96 | }); 97 | }; 98 | 99 | MobileNav.prototype.init = function () { 100 | // Since the Mobile navigation is not included in IE8 101 | // We detect features we need to use only available in IE9+ https://caniuse.com/#feat=addeventlistener 102 | // http://responsivenews.co.uk/post/18948466399/cutting-the-mustard 103 | const featuresNeeded = ( 104 | 'querySelector' in document 105 | && 'addEventListener' in window 106 | ); 107 | 108 | if (!featuresNeeded) { 109 | return; 110 | } 111 | 112 | this.includeAria(); 113 | this.bindUIEvents(); 114 | }; 115 | 116 | export default MobileNav; 117 | -------------------------------------------------------------------------------- /app/assets/javascript/vendor/common.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) 3 | : typeof define === 'function' && define.amd ? define('GOVUKFrontend', ['exports'], factory) 4 | : (factory((global.GOVUKFrontend = {}))); 5 | }(this, ((exports) => { 6 | /** 7 | * TODO: Ideally this would be a NodeList.prototype.forEach polyfill 8 | * This seems to fail in IE8, requires more investigation. 9 | * See: https://github.com/imagitama/nodelist-foreach-polyfill. 10 | * 11 | * @param nodes 12 | * @param callback 13 | */ 14 | function nodeListForEach(nodes, callback) { 15 | if (window.NodeList.prototype.forEach) { 16 | return nodes.forEach(callback); 17 | } 18 | for (let i = 0; i < nodes.length; i++) { 19 | callback.call(window, nodes[i], i, nodes); 20 | } 21 | } 22 | 23 | // Used to generate a unique string, allows multiple instances of the component without 24 | // Them conflicting with each other. 25 | // https://stackoverflow.com/a/8809472 26 | function generateUniqueID() { 27 | let d = new Date().getTime(); 28 | if (typeof window.performance !== 'undefined' && typeof window.performance.now === 'function') { 29 | d += window.performance.now(); // use high-precision timer if available 30 | } 31 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { 32 | const r = (d + Math.random() * 16) % 16 | 0; 33 | d = Math.floor(d / 16); 34 | return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16); 35 | }); 36 | } 37 | 38 | exports.nodeListForEach = nodeListForEach; 39 | exports.generateUniqueID = generateUniqueID; 40 | }))); 41 | -------------------------------------------------------------------------------- /app/assets/sass/_app-pane.scss: -------------------------------------------------------------------------------- 1 | $toc-width: 260px; 2 | $toc-width-tablet: 210px; 3 | 4 | .app-pane .app-pane--enabled { 5 | @include govuk-media-query($from: tablet) { 6 | display: flex; 7 | flex-direction: column; 8 | } 9 | } 10 | 11 | .app-pane__body { 12 | @include govuk-media-query($from: tablet) { 13 | display: flex; 14 | position: relative; 15 | min-height: 0; 16 | overflow: inherit; 17 | } 18 | 19 | @include govuk-media-query(1160px) { 20 | width: 100%; 21 | } 22 | } 23 | 24 | .app-pane__subnav { 25 | @include govuk-media-query($until: tablet) { 26 | display: none; 27 | } 28 | @include govuk-media-query($from: tablet) { 29 | width: $toc-width-tablet; 30 | flex: 0 0 auto; 31 | } 32 | @include govuk-media-query($from: desktop) { 33 | width: $toc-width; 34 | } 35 | } 36 | 37 | .app-pane__subnav-mobile-overview { 38 | @include govuk-media-query($from: tablet) { 39 | display: none; 40 | } 41 | } 42 | 43 | .app-pane__content { 44 | @include govuk-media-query($from: tablet) { 45 | display: flex; 46 | min-width: 0; 47 | flex: 1 1 100%; 48 | flex-direction: column; 49 | } 50 | } 51 | 52 | .no-flexbox.no-flexboxtweener { 53 | .app-pane { 54 | height: auto; 55 | overflow: visible; 56 | @include govuk-clearfix; 57 | } 58 | 59 | .app-pane__body { 60 | display: block; 61 | } 62 | 63 | .app-pane__subnav { 64 | width: $toc-width; 65 | float: left; 66 | overflow-x: hidden; 67 | border-right: 0; 68 | } 69 | 70 | .app-pane__content { 71 | margin-left: -1px; 72 | overflow-x: hidden; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /app/assets/sass/_app-phase-banner.scss: -------------------------------------------------------------------------------- 1 | .app-phase-banner { 2 | @include govuk-media-query($until: tablet) { 3 | margin-right: 0; 4 | margin-left: 0; 5 | } 6 | 7 | @include govuk-media-query($from: tablet) { 8 | border-bottom: 0; 9 | } 10 | } 11 | 12 | .app-phase-banner--no-border { 13 | border-bottom: 0; 14 | } -------------------------------------------------------------------------------- /app/assets/sass/_back-to-top.scss: -------------------------------------------------------------------------------- 1 | .app-back-to-top { 2 | margin-top: govuk-spacing(4); 3 | margin-bottom: govuk-spacing(6); 4 | } 5 | 6 | @include govuk-media-query($from: tablet) { 7 | .app-back-to-top { 8 | position: absolute; 9 | bottom: 0; 10 | left: 0; 11 | margin-top: auto; 12 | margin-bottom: govuk-spacing(8); 13 | } 14 | 15 | .js-enabled .app-back-to-top--fixed { 16 | position: fixed; 17 | top: calc(100% - #{govuk-spacing(8)}); 18 | bottom: auto; 19 | left: auto; 20 | } 21 | 22 | .js-enabled .app-back-to-top--hidden .app-back-to-top__link { 23 | @include govuk-visually-hidden-focusable; 24 | } 25 | } 26 | 27 | .app-back-to-top__icon { 28 | display: inline-block; 29 | width: .8em; 30 | height: 1em; 31 | margin-top: -(govuk-spacing(1)); 32 | margin-right: govuk-spacing(2); 33 | vertical-align: middle; 34 | } 35 | -------------------------------------------------------------------------------- /app/assets/sass/_contact-panel.scss: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | #CONTACT PANEL 3 | ========================================================================== */ 4 | 5 | .app-contact-panel { 6 | @include govuk-responsive-padding(3); 7 | background-color: govuk-colour("purple"); 8 | color: govuk-colour("white"); 9 | } 10 | 11 | 12 | .app-contact-panel__heading, 13 | .app-contact-panel__body, 14 | .app-contact-panel__link { 15 | color: govuk-colour("white"); 16 | } 17 | 18 | 19 | .app-contact-panel__heading { 20 | @extend .govuk-heading-m; 21 | } 22 | 23 | 24 | .app-contact-panel__body { 25 | @include govuk-font(19); 26 | margin-bottom: 0; 27 | } 28 | 29 | 30 | .app-contact-panel__link:link, 31 | .app-contact-panel__link:active, 32 | .app-contact-panel__link:visited { 33 | color: govuk-colour("white"); 34 | } 35 | 36 | 37 | .app-contact-panel__link:hover { 38 | color: lighten(govuk-colour("purple"), 45%); 39 | } 40 | 41 | 42 | .app-contact-panel__link:focus { 43 | color: govuk-colour("black"); 44 | } 45 | -------------------------------------------------------------------------------- /app/assets/sass/_cookie-banner.scss: -------------------------------------------------------------------------------- 1 | /* Cookie banner */ 2 | .cookie-banner, 3 | .cookie-banner-noscript { 4 | background: #f3f2f1; 5 | & form { 6 | display: inline; 7 | } 8 | } 9 | 10 | .cookie-banner--main, 11 | .cookie-banner--accept, 12 | .cookie-banner--reject { 13 | margin-bottom: 0; 14 | } 15 | 16 | .hidden { 17 | display: none; 18 | } 19 | 20 | .cookie-banner--reject:focus, 21 | .cookie-banner--accept:focus { 22 | outline: none; 23 | } 24 | .cookie-banner--reject p, 25 | .cookie-banner--accept p, 26 | .cookie-banner-accept--hide, 27 | .cookie-banner-reject--hide, 28 | .cookie-banner--hide { 29 | display: inline-block; 30 | } 31 | 32 | .cookie-banner--hide, 33 | .cookie-banner-accept--hide, 34 | .cookie-banner-reject--hide { 35 | float: none; 36 | } 37 | 38 | @media (min-width: 840px) { 39 | .cookie-banner--hide, 40 | .cookie-banner-accept--hide, 41 | .cookie-banner-reject--hide { 42 | float: right; 43 | margin-right: 30px; 44 | width: auto; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/assets/sass/_example.scss: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | #EXAMPLE 3 | ========================================================================== */ 4 | .app-example-wrapper { 5 | @include govuk-responsive-margin(6, "top"); 6 | @include govuk-responsive-margin(6, "bottom"); 7 | 8 | // HACK - this feels like a hack, will need revisiting 9 | @supports (margin: max(0px)) { 10 | .govuk-width-container { 11 | margin-right: max(30px, 15px); 12 | margin-left: max(30px, 15px); 13 | } 14 | } 15 | } 16 | 17 | .app-example { 18 | position: relative; 19 | border: 1px solid $govuk-border-colour; 20 | border-bottom: 0; 21 | // Add a 'checkerboard' background 22 | background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAJUlEQVQoU2P88ePHfwY0wMHBwYguxjgUFKI7GsTH5m4M3w1ChQAZTSeO0/AZpgAAAABJRU5ErkJggg==") repeat; 23 | } 24 | 25 | .app-example--tabs { 26 | @include govuk-responsive-margin(0, "bottom"); 27 | } 28 | 29 | .app-example__toolbar { 30 | padding: 10px; 31 | border-bottom: 1px solid $govuk-border-colour; 32 | background: $govuk-body-background-colour; 33 | } 34 | 35 | pre, 36 | .app-example__code { 37 | background-color: govuk-colour("light-grey"); 38 | padding: 10px 10px 0 0; 39 | position: relative; 40 | @include govuk-font($size: 19); 41 | } 42 | 43 | .app-example__new-window { 44 | @include govuk-font($size: 14); 45 | } 46 | 47 | .app-example__copy-code-button { 48 | font-family: arial, sans-serif; 49 | z-index: 1; 50 | min-width: 110px; 51 | padding: 3px 10px; 52 | margin-right: 0; 53 | margin-left: auto; 54 | display: block; 55 | border: 1px solid #00823b; 56 | color: #00823b; 57 | box-shadow: 0 2px 0 0 govuk-colour("green"); 58 | text-align: center; 59 | text-decoration: none; 60 | cursor: pointer; 61 | font-size: 1rem; 62 | line-height: 1.25; 63 | background-color: govuk-colour("white"); 64 | 65 | &:active, 66 | &:focus { 67 | padding: 2px 10px; 68 | border: 2px solid govuk-colour("yellow"); 69 | outline: 2px solid transparent; 70 | box-shadow: none; 71 | } 72 | } 73 | 74 | .app-example__table-col { 75 | width: 33.3%; 76 | } -------------------------------------------------------------------------------- /app/assets/sass/_header.scss: -------------------------------------------------------------------------------- 1 | @include govuk-exports("app-header") { 2 | 3 | // Move the blue border from the container to the header so that it spans 4 | // the full width of the page 5 | .app-header { 6 | border-bottom: 10px solid $dwp-brand-colour; 7 | } 8 | 9 | .app-header__container { 10 | margin-bottom: 0; 11 | border-bottom: 0; 12 | } 13 | 14 | // Override the default 33% width on the logo in GOV.UK Frontend (prevents 15 | // unnecessary wrapping of "GOV.UK Design System" on smaller tablet / desktop 16 | // viewports) 17 | .app-header__logo { 18 | display: inline; 19 | float: left; 20 | 21 | @include govuk-media-query($from: tablet) { 22 | width: 100%; 23 | display: block; 24 | } 25 | } 26 | 27 | .app-header-mobile-nav-toggler-wrapper { 28 | margin-top: -10px; 29 | display: block; 30 | float: right; 31 | } 32 | 33 | .app-header-mobile-nav-toggler { 34 | display: none; 35 | min-height: 40px; // match the height of the search box 36 | margin-top: govuk-spacing(2); 37 | margin-bottom: govuk-spacing(2); 38 | padding-right: govuk-spacing(1); 39 | padding-left: govuk-spacing(1); 40 | border: 1px solid transparent; // Override the button default border, keep this around for when users change their colours 41 | box-shadow: none; // Override the button default box shadow 42 | 43 | &, 44 | &:hover { 45 | background-color: transparent; // Override the button default green 46 | } 47 | 48 | &::after { 49 | @include govuk-shape-arrow($direction: down, $base: 10px, $display: inline-block); 50 | content: ""; 51 | margin-left: govuk-spacing(1); 52 | border-top-color: currentColor; 53 | } 54 | 55 | &--active::after { 56 | @include govuk-shape-arrow($direction: up, $base: 10px, $display: inline-block); 57 | border-bottom-color: currentColor; 58 | } 59 | 60 | .js-enabled & { 61 | @include govuk-media-query($until: tablet) { 62 | display: inline; 63 | } 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/assets/sass/_highlight.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | Theme: GitHub 3 | Description: Light theme as seen on github.com 4 | Author: github.com 5 | Maintainer: @Hirse 6 | Updated: 2021-05-15 7 | 8 | Outdated base version: https://github.com/primer/github-syntax-light 9 | Current colors taken from GitHub's CSS 10 | */ 11 | 12 | .hljs { 13 | color: #24292e; 14 | } 15 | 16 | .hljs-doctag, 17 | .hljs-keyword, 18 | .hljs-meta .hljs-keyword, 19 | .hljs-template-tag, 20 | .hljs-template-variable, 21 | .hljs-type, 22 | .hljs-variable.language_ { 23 | /* prettylights-syntax-keyword */ 24 | color: #d73a49; 25 | } 26 | 27 | .hljs-title, 28 | .hljs-title.class_, 29 | .hljs-title.class_.inherited__, 30 | .hljs-title.function_ { 31 | /* prettylights-syntax-entity */ 32 | color: #6f42c1; 33 | } 34 | 35 | .hljs-attr, 36 | .hljs-attribute, 37 | .hljs-literal, 38 | .hljs-meta, 39 | .hljs-number, 40 | .hljs-operator, 41 | .hljs-variable, 42 | .hljs-selector-attr, 43 | .hljs-selector-class, 44 | .hljs-selector-id { 45 | /* prettylights-syntax-constant */ 46 | color: #005cc5; 47 | } 48 | 49 | .hljs-regexp, 50 | .hljs-string, 51 | .hljs-meta .hljs-string { 52 | /* prettylights-syntax-string */ 53 | color: #032f62; 54 | } 55 | 56 | .hljs-built_in, 57 | .hljs-symbol { 58 | /* prettylights-syntax-variable */ 59 | color: #e36209; 60 | } 61 | 62 | .hljs-comment, 63 | .hljs-code, 64 | .hljs-formula { 65 | /* prettylights-syntax-comment */ 66 | color: #6a737d; 67 | } 68 | 69 | .hljs-name, 70 | .hljs-quote, 71 | .hljs-selector-tag, 72 | .hljs-selector-pseudo { 73 | /* prettylights-syntax-entity-tag */ 74 | color: #22863a; 75 | } 76 | 77 | .hljs-subst { 78 | /* prettylights-syntax-storage-modifier-import */ 79 | color: #24292e; 80 | } 81 | 82 | .hljs-section { 83 | /* prettylights-syntax-markup-heading */ 84 | color: #005cc5; 85 | font-weight: bold; 86 | } 87 | 88 | .hljs-bullet { 89 | /* prettylights-syntax-markup-list */ 90 | color: #735c0f; 91 | } 92 | 93 | .hljs-emphasis { 94 | /* prettylights-syntax-markup-italic */ 95 | color: #24292e; 96 | font-style: italic; 97 | } 98 | 99 | .hljs-strong { 100 | /* prettylights-syntax-markup-bold */ 101 | color: #24292e; 102 | font-weight: bold; 103 | } 104 | 105 | .hljs-addition { 106 | /* prettylights-syntax-markup-inserted */ 107 | color: #22863a; 108 | background-color: #f0fff4; 109 | } 110 | 111 | .hljs-deletion { 112 | /* prettylights-syntax-markup-deleted */ 113 | color: #b31d28; 114 | background-color: #ffeef0; 115 | } 116 | -------------------------------------------------------------------------------- /app/assets/sass/_layout.scss: -------------------------------------------------------------------------------- 1 | .ds-grid-row { 2 | padding: 0 15px; 3 | margin-bottom: 30px; 4 | 5 | @include govuk-media-query($from: desktop) { 6 | padding: 0; 7 | margin-bottom: 50px; 8 | } 9 | 10 | &--item { 11 | box-sizing: border-box; 12 | float: left; 13 | width: 100%; 14 | margin: 0; 15 | margin-bottom: 30px; 16 | 17 | &:last-of-type { 18 | margin-right: 0; 19 | } 20 | 21 | @include govuk-media-query($from: desktop) { 22 | width: 30.333%; 23 | margin-left: 1.5%; 24 | margin-right: 1.5%; 25 | margin-bottom: 0; 26 | } 27 | } 28 | } 29 | 30 | @supports (display: grid) { 31 | 32 | .ds-grid-row { 33 | display: grid; 34 | grid-template-columns: 1fr; 35 | grid-gap: 30px; 36 | margin: 0; 37 | padding: 0; 38 | 39 | &--item { 40 | float: none; 41 | width: 100%; 42 | padding: 0; 43 | margin: 0; 44 | } 45 | 46 | @include govuk-media-query($from: desktop) { 47 | grid-template-columns: 1fr 1fr 1fr; 48 | grid-auto-rows: max-content; 49 | 50 | &--item { 51 | margin-bottom: 20px; 52 | } 53 | } 54 | 55 | } 56 | 57 | } -------------------------------------------------------------------------------- /app/assets/sass/_masthead.scss: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | #MASTHEAD 3 | // Ideal line length (https://pearsonified.com/typography) 4 | ========================================================================== */ 5 | 6 | .app-masthead { 7 | @include govuk-responsive-padding(6, "top"); 8 | @include govuk-responsive-padding(6, "bottom"); 9 | background-color: govuk-colour("purple"); 10 | color: govuk-colour("white"); 11 | margin-top: -1px; // Covers the navigation border bottom 12 | } 13 | 14 | 15 | .app-masthead__title { 16 | @include govuk-responsive-margin(6, "bottom"); 17 | color: govuk-colour("white"); 18 | max-width: 1057px; // Desired CPL 50 (headings) chars at a font size of 48px 19 | } 20 | 21 | .app-masthead__description { 22 | @include govuk-font(24); 23 | color: govuk-colour("white"); 24 | margin-bottom: 0; 25 | max-width: 793px; // Desired CPL 75 (paragraphs) chars at a font size of 24px 26 | 27 | @include govuk-media-query($from: mobile, $until: desktop) { 28 | margin-bottom: 20px; 29 | } 30 | 31 | } 32 | 33 | .app-masthead__new { 34 | border: 2px solid govuk-colour("light-purple"); 35 | padding: 15px; 36 | 37 | ul { 38 | @extend %govuk-list; 39 | @extend %govuk-list--bullet; 40 | color: govuk-colour("white"); 41 | } 42 | } -------------------------------------------------------------------------------- /app/assets/sass/_mobile-navigation.scss: -------------------------------------------------------------------------------- 1 | .app-mobile-nav { 2 | display: none; 3 | border-bottom: 1px solid $govuk-border-colour; 4 | } 5 | 6 | .app-mobile-nav--active { 7 | display: block; 8 | 9 | @include govuk-media-query($from: tablet) { 10 | display: none; 11 | } 12 | } 13 | 14 | .no-js .app-mobile-nav { 15 | @include govuk-media-query($until: tablet) { 16 | display: block; 17 | } 18 | } 19 | 20 | .app-mobile-nav__list { 21 | margin: 0; 22 | padding: 0; 23 | list-style: none; 24 | } 25 | 26 | .app-mobile-nav-subnav-toggler { 27 | position: relative; 28 | padding: 16px govuk-spacing(4) 17px govuk-spacing(4); 29 | background-color: govuk-colour("light-grey"); 30 | } 31 | 32 | .app-mobile-nav-subnav-toggler__link { 33 | @include govuk-typography-weight-bold; // Override .govuk-link weight 34 | font-size: 19px; // We do not have a font mixin that produces 19px on mobile 35 | font-size: govuk-px-to-rem(19px); // sass-lint:disable-line no-duplicate-properties 36 | 37 | &:not(:focus):hover { 38 | color: $govuk-link-colour; 39 | } 40 | } 41 | 42 | .app-mobile-nav-subnav-toggler__link, 43 | .app-mobile-nav__link { 44 | text-decoration: none; 45 | 46 | // Expand the touch area of the link to the full menu width 47 | &:after { 48 | content: ""; 49 | position: absolute; 50 | top: 0; 51 | right: 0; 52 | bottom: 0; 53 | left: 0; 54 | } 55 | } 56 | 57 | .app-mobile-nav__subnav { 58 | display: none; 59 | padding-top: govuk-spacing(2); 60 | padding-bottom: govuk-spacing(2); 61 | border-top: 1px solid govuk-colour("light-grey"); 62 | border-bottom: 1px solid govuk-colour("light-grey"); 63 | } 64 | 65 | .js-enabled .app-mobile-nav__subnav--active { 66 | display: block; 67 | } 68 | 69 | .app-mobile-nav__section-item { 70 | position: relative; 71 | } 72 | 73 | .app-mobile-nav__subnav-item { 74 | display: block; 75 | position: relative; 76 | padding: (govuk-spacing(2) + 2px) govuk-spacing(4); 77 | } 78 | 79 | .app-mobile-nav__subnav-item--current { 80 | $_current-indicator-width: 4px; 81 | padding-left: govuk-spacing(4) - $_current-indicator-width; 82 | border-left: $_current-indicator-width solid govuk-colour("purple"); 83 | } 84 | 85 | .app-mobile-nav__theme { 86 | @include govuk-typography-common; 87 | margin: 0; 88 | padding: govuk-spacing(4) govuk-spacing(4) govuk-spacing(1) govuk-spacing(4); 89 | color: govuk-colour("dark-grey"); 90 | // Font is defined as a hard 19px so 91 | // it does not re-size on mobile viewport 92 | font-size: 19px; 93 | font-size: govuk-px-to-rem(19px); // sass-lint:disable-line no-duplicate-properties 94 | font-weight: normal; 95 | } -------------------------------------------------------------------------------- /app/assets/sass/_navigation.scss: -------------------------------------------------------------------------------- 1 | $navigation-height: 50px; 2 | 3 | .app-navigation { 4 | @include govuk-font(19, $weight: bold); 5 | box-sizing: border-box; 6 | width: 100%; 7 | background-color: $app-light-grey; 8 | 9 | @include govuk-media-query($until: tablet) { 10 | display: none; 11 | } 12 | } 13 | 14 | .app-navigation__list { 15 | position: relative; 16 | left: -(govuk-spacing(3)); 17 | margin: 0; 18 | padding: 0; 19 | list-style: none; 20 | } 21 | 22 | .app-navigation__list-item { 23 | box-sizing: border-box; 24 | display: block; 25 | position: relative; 26 | height: $navigation-height; 27 | padding: 0 govuk-spacing(3); 28 | float: left; 29 | line-height: $navigation-height; 30 | } 31 | 32 | .app-navigation__list-item--selected { 33 | border-bottom: 4px solid govuk-colour(purple); 34 | 35 | } 36 | 37 | .app-navigation__list-item--current { 38 | border-bottom: 4px solid govuk-colour(purple); 39 | } 40 | 41 | .app-navigation__link { 42 | // color: govuk-colour(purple) !important; 43 | @include govuk-typography-weight-bold; 44 | text-decoration: none; 45 | 46 | &:not(:focus):hover { 47 | color: govuk-colour(purple); 48 | text-decoration: underline; 49 | } 50 | 51 | // Extend the touch area of the link to the list 52 | &:after { 53 | content: ""; 54 | position: absolute; 55 | top: 0; 56 | right: 0; 57 | bottom: 0; 58 | left: 0; 59 | } 60 | } 61 | 62 | .app-navigation__list-item--current .app-navigation__link:hover { 63 | text-decoration: none; 64 | } 65 | -------------------------------------------------------------------------------- /app/assets/sass/_sub-navigation.scss: -------------------------------------------------------------------------------- 1 | @include govuk-exports("app-subnav") { 2 | 3 | .app-subnav { 4 | // Since the back to top link is outside the flow of the document we need to create a space for it. 5 | // This number is magic and was determined by manually judging the visual spacing. 6 | margin-bottom: 100px; 7 | padding: govuk-spacing(6) govuk-spacing(3) 0 0; 8 | @include govuk-font(16); 9 | } 10 | 11 | .app-subnav__section { 12 | margin: 0 0 govuk-spacing(4); 13 | padding: 0; 14 | list-style-type: none; 15 | } 16 | 17 | .app-subnav__link { 18 | padding: 2px 0; 19 | @include govuk-font(16); 20 | 21 | &:not(:focus):hover { 22 | color: $govuk-link-colour; 23 | } 24 | } 25 | 26 | .app-subnav__section-item { 27 | position: relative; 28 | margin-bottom: govuk-spacing(1); 29 | padding-top: govuk-spacing(1); 30 | padding-bottom: govuk-spacing(1); 31 | } 32 | 33 | .app-subnav__section-item--current { 34 | $_current-indicator-width: 4px; 35 | margin-left: -(govuk-spacing(2) + $_current-indicator-width); 36 | padding-left: govuk-spacing(2); 37 | border-left: $_current-indicator-width solid govuk-colour("purple"); 38 | background-color: $app-light-grey; 39 | } 40 | 41 | .app-subnav__section-item--current .app-subnav__link { 42 | font-weight: bold; 43 | } 44 | 45 | .app-subnav__section-item--top { 46 | .app-subnav__link { 47 | position: relative; 48 | z-index: 2; 49 | } 50 | 51 | &:after { 52 | content: ''; 53 | display: block; 54 | $_current-indicator-width: 4px; 55 | padding-left: govuk-spacing(2); 56 | border-left: $_current-indicator-width solid govuk-colour("purple"); 57 | background-color: $app-light-grey; 58 | position: absolute; 59 | top: 0; 60 | left: -(govuk-spacing(4) + $_current-indicator-width); 61 | width: 100%; 62 | height: 35px; 63 | } 64 | } 65 | 66 | .app-subnav__section-item--bold .app-subnav__link { 67 | font-weight: bold; 68 | position: relative; 69 | z-index: 2; 70 | } 71 | 72 | .app-subnav__section--nested { 73 | margin-top: govuk-spacing(2); 74 | margin-bottom: 0; 75 | padding-left: govuk-spacing(4); 76 | } 77 | 78 | .app-subnav__section--nested .app-subnav__section-item::before { 79 | margin-left: -(govuk-spacing(4)); 80 | color: govuk-colour("dark-grey"); 81 | } 82 | 83 | .app-subnav__section--nested .app-subnav__link { 84 | padding-left: 0; 85 | font-weight: normal; 86 | } 87 | 88 | .app-subnav__theme { 89 | margin: 0; 90 | padding: govuk-spacing(2) govuk-spacing(3) govuk-spacing(2) 0; 91 | color: govuk-colour("dark-grey"); 92 | @include govuk-font(19); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /app/assets/sass/_tabs.scss: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | #TABS 3 | ========================================================================== */ 4 | 5 | .app-tabs { 6 | background: govuk-colour("white"); 7 | margin-bottom: govuk-spacing(6); 8 | } 9 | 10 | 11 | .app-tabs__list { 12 | border: 1px solid $govuk-border-colour; 13 | list-style: none; 14 | margin: 0; 15 | padding: 0; 16 | font-size: 0; // Remove white space when using display: inline-block 17 | 18 | } 19 | 20 | 21 | .app-tabs__list-item { 22 | display: inline-block; 23 | margin: 0; 24 | margin-bottom: 0; 25 | 26 | } 27 | 28 | 29 | .app-tabs__tab { 30 | @include govuk-font($size: 19, $weight: bold); 31 | background-color: govuk-colour("white"); 32 | color: govuk-colour("purple"); 33 | display: inline-block; 34 | padding: 20px; 35 | position: relative; 36 | border: 0; 37 | cursor: pointer; 38 | text-decoration: underline; 39 | 40 | &:link, 41 | &:active, 42 | &:visited { 43 | background-color: govuk-colour("white"); 44 | color: govuk-colour("purple"); 45 | } 46 | 47 | &:hover { 48 | text-decoration-skip-ink: none; 49 | text-decoration-thickness: 3px; 50 | color: govuk-colour("light-purple"); 51 | } 52 | 53 | &:focus { 54 | z-index: 2; // Focus state must sit above 55 | text-decoration-skip-ink: none; 56 | text-decoration-thickness: 3px; 57 | color: $govuk-focus-text-colour; 58 | background-color: $govuk-focus-colour; 59 | box-shadow: 0 -2px $govuk-focus-colour, 0 4px $govuk-focus-text-colour; 60 | border-color: $govuk-focus-text-colour; 61 | text-decoration: none; 62 | } 63 | 64 | &[aria-expanded=true] { 65 | color: govuk-colour("black"); 66 | margin-bottom: -1px; 67 | padding-bottom: 21px; 68 | border-left: 1px solid $govuk-border-colour; 69 | border-right: 1px solid $govuk-border-colour; 70 | } 71 | 72 | &:first-of-type { 73 | &[aria-expanded=true] { 74 | border-left: 0; 75 | } 76 | } 77 | 78 | } 79 | 80 | 81 | .app-tabs__panel { 82 | @include govuk-font($size: 19); 83 | border: 1px solid $govuk-border-colour; 84 | border-top: 0; 85 | position: relative; 86 | padding: 20px; 87 | 88 | *:last-child { 89 | margin-bottom: 0; // Remove margin bottom from any last element 90 | } 91 | 92 | p { 93 | background-color: govuk-colour("white"); 94 | max-width: 100% !important; 95 | padding: govuk-spacing(2); 96 | } 97 | 98 | &__details { 99 | margin-bottom: 16px; 100 | p { 101 | padding: 0; 102 | } 103 | } 104 | 105 | &__code { 106 | position: relative; 107 | } 108 | } 109 | 110 | // add slight indent to css code snippet 111 | .hljs-attribute { 112 | padding-left: 15px; 113 | } -------------------------------------------------------------------------------- /app/assets/sass/_timeout-warning.scss: -------------------------------------------------------------------------------- 1 | @import "vendor/dialog-polyfill.0.5.0"; 2 | 3 | .govuk-timeout-warning { 4 | display: none; 5 | // @include govuk-responsive-padding(6); 6 | // Setting width allows IE to center dialog vertically 7 | width: 100%; 8 | 9 | // To do: allow this to be customised 10 | max-width: 500px; 11 | 12 | .govuk-button { 13 | margin: 0 govuk-spacing(2) govuk-spacing(3) 0; 14 | @include govuk-media-query($from: tablet) { 15 | margin-bottom: govuk-spacing(0); 16 | } 17 | } 18 | 19 | &[open] { 20 | display: block; 21 | 22 | $backdrop-colour: rgba(0, 0, 0, .8); 23 | 24 | // Backdrop styles for browsers with native support 25 | &+ .backdrop { 26 | background: $backdrop-colour; 27 | } 28 | 29 | // Backdrop styles for browsers using 30 | // Keep these two backdrop styles separate - Safari didn't 31 | // work when combined 32 | &::backdrop { 33 | background: $backdrop-colour; 34 | } 35 | } 36 | } 37 | 38 | // Stop background scrolling while dialog open. 39 | .govuk-timeout-warning-overlay { 40 | overflow: hidden; 41 | } 42 | 43 | .govuk-notification-banner--blue { 44 | background-color: $govuk-blue; 45 | border-color: $govuk-blue; 46 | } 47 | 48 | .js-enabled .dwp-timeout-warning-fallback { 49 | display: none; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /app/assets/sass/_toggle-to-welsh.scss: -------------------------------------------------------------------------------- 1 | .dwp-language-toggle { 2 | font-family: Arial,sans-serif; 3 | font-size: 14px; 4 | } 5 | .dwp-language-toggle__list { 6 | margin-top: 1em; 7 | text-align: right; 8 | } 9 | .dwp-language-toggle__list-item { 10 | display: inline-block; 11 | } 12 | .dwp-language-toggle__list-item:first-child:after { 13 | content: ""; 14 | display: inline-block; 15 | border-right: 1px solid #0b0c0c; 16 | position: relative; 17 | top: .1875em; 18 | height: 1em; 19 | } -------------------------------------------------------------------------------- /app/assets/sass/application-ie8.scss: -------------------------------------------------------------------------------- 1 | // By setting $govuk-is-ie8 to true, we create a version of the stylesheet that 2 | // targets IE8 – e.g. conditionally including or excluding styles, and 3 | // rasterizing media queries. 4 | $govuk-is-ie8: true; 5 | 6 | @import "application"; 7 | -------------------------------------------------------------------------------- /app/assets/sass/vendor/dialog-polyfill.0.5.0.css: -------------------------------------------------------------------------------- 1 | dialog { 2 | position: absolute; 3 | left: 0; right: 0; 4 | width: -moz-fit-content; 5 | width: -webkit-fit-content; 6 | width: fit-content; 7 | height: -moz-fit-content; 8 | height: -webkit-fit-content; 9 | height: fit-content; 10 | margin: auto; 11 | border: solid; 12 | padding: 1em; 13 | background: white; 14 | color: black; 15 | display: block; 16 | } 17 | 18 | dialog:not([open]) { 19 | display: none; 20 | } 21 | 22 | dialog + .backdrop { 23 | position: fixed; 24 | top: 0; right: 0; bottom: 0; left: 0; 25 | background: rgba(0,0,0,0.1); 26 | } 27 | 28 | ._dialog_overlay { 29 | position: fixed; 30 | top: 0; right: 0; bottom: 0; left: 0; 31 | } 32 | 33 | dialog.fixed { 34 | position: fixed; 35 | top: 50%; 36 | transform: translate(0, -50%); 37 | } 38 | -------------------------------------------------------------------------------- /app/middleware/accessibility.js: -------------------------------------------------------------------------------- 1 | const renderA11yStatement = (req, res) => res.render( 2 | '_accessibility.njk', 3 | ); 4 | module.exports = { renderA11yStatement }; -------------------------------------------------------------------------------- /app/middleware/cookies/cookieDetails.js: -------------------------------------------------------------------------------- 1 | const renderCookieDetails = (req, res) => res.render( 2 | '_cookie-details.njk', 3 | ); 4 | module.exports = { renderCookieDetails }; 5 | -------------------------------------------------------------------------------- /app/middleware/cookies/cookiePolicy.js: -------------------------------------------------------------------------------- 1 | const { setCookieChoice } = require('./cookiesConsent'); 2 | 3 | const renderCookiePolicy = (req, res) => { 4 | res.locals.cookieConsent = req.cookies.seen_cookie_message; 5 | res.render( 6 | '_cookie-policy.njk', 7 | ); 8 | }; 9 | 10 | const cookiePolicyPostHandler = (req, res, next) => { 11 | const { cookieChoice } = req.body; 12 | if (!cookieChoice) { 13 | res.locals.validationError = true; 14 | next(); 15 | } else { 16 | setCookieChoice(req, res); 17 | } 18 | }; 19 | 20 | module.exports = { renderCookiePolicy, cookiePolicyPostHandler }; 21 | -------------------------------------------------------------------------------- /app/middleware/cookies/cookiesConsent.js: -------------------------------------------------------------------------------- 1 | const oneYearInMilliseconds = 1000 * 60 * 60 * 24 * 365; 2 | const CONSENT_COOKIE = 'dwp_analytics'; 3 | const COOKIE_DECISION_MADE = 'cookie_decision_made'; 4 | 5 | const consentCookieOptions = (res, cookieChoice) => { 6 | res.cookie(CONSENT_COOKIE, cookieChoice, { 7 | path: '/', 8 | maxAge: oneYearInMilliseconds, 9 | httpOnly: false, 10 | sameSite: true, 11 | secure: false, 12 | }); 13 | }; 14 | 15 | const cookieDecisionMadeOptions = (res, flag) => { 16 | res.cookie(COOKIE_DECISION_MADE, flag, { 17 | path: '/', 18 | maxAge: oneYearInMilliseconds, 19 | httpOnly: false, 20 | sameSite: true, 21 | secure: false, 22 | }); 23 | }; 24 | 25 | const setCookieChoice = (req, res) => { 26 | const { cookieChoice } = req.body; 27 | 28 | if (cookieChoice) { 29 | consentCookieOptions(res, cookieChoice); 30 | cookieDecisionMadeOptions(res, true); 31 | } 32 | if (res.locals.currentUrl === '/cookie-policy') { 33 | res.redirect('/'); 34 | } else { 35 | res.redirect('back'); 36 | } 37 | }; 38 | 39 | const getCookieChoice = (req, res, next) => { 40 | const cookieChoice = req.cookies[CONSENT_COOKIE]; 41 | const cookieDecisionMade = req.cookies[COOKIE_DECISION_MADE]; 42 | 43 | if (cookieDecisionMade || cookieChoice) { 44 | res.locals.cookieChoiceJustMade = cookieDecisionMade; 45 | res.clearCookie(COOKIE_DECISION_MADE); 46 | 47 | if (cookieChoice) { 48 | res.locals.cookieMessage = cookieChoice; 49 | res.locals.currentUrl = req.originalUrl; 50 | } 51 | } 52 | 53 | next(); 54 | }; 55 | 56 | module.exports = { setCookieChoice, getCookieChoice }; 57 | -------------------------------------------------------------------------------- /app/middleware/errorHandler.js: -------------------------------------------------------------------------------- 1 | const errorHandler = (err, req, res, next) => { 2 | console.error('WHAT > > > ', err); 3 | res.status(err.status || 500); 4 | res.render('_page-not-found.njk') 5 | } 6 | 7 | module.exports = { errorHandler }; 8 | -------------------------------------------------------------------------------- /app/middleware/sitemap.js: -------------------------------------------------------------------------------- 1 | const renderSitemap = (req, res) => res.render( 2 | '_sitemap.njk', 3 | ); 4 | module.exports = { renderSitemap }; -------------------------------------------------------------------------------- /app/middleware/urlPartials.js: -------------------------------------------------------------------------------- 1 | const urlPartials = (req, res, next) => { 2 | //store original url as array in locals, removing the first item as it is always an empty string 3 | const urlPartials = req.originalUrl.split('/').slice(1); 4 | res.locals.urlPartials = urlPartials; 5 | next(); 6 | } 7 | 8 | module.exports = { urlPartials }; -------------------------------------------------------------------------------- /app/routes/auto.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const { navigationDataLoader } = require('../utils/navigation-data-loader'); 4 | const { contentLoader } = require('../utils/content-loader'); 5 | const { dotHtmlMatch, slugMatch } = require('../utils/regexes') 6 | 7 | router.use(navigationDataLoader); 8 | router.use(contentLoader); 9 | 10 | router.get(dotHtmlMatch, function (req, res) { 11 | var path = req.path; 12 | var parts = path.split('.'); 13 | parts.pop(); 14 | path = parts.join('.'); 15 | res.redirect(path); 16 | }); 17 | 18 | router.get(slugMatch, function (req, res) { 19 | const path = req.params[0]; 20 | res.render(`${path}/index`) 21 | }) 22 | 23 | module.exports = router; 24 | -------------------------------------------------------------------------------- /app/routes/index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | const router = express.Router(); 4 | const { navigationDataLoader } = require('../utils/navigation-data-loader'); 5 | const { renderCookiePolicy, cookiePolicyPostHandler } = require('../middleware/cookies/cookiePolicy'); 6 | const { renderCookieDetails } = require('../middleware/cookies/cookieDetails'); 7 | const { setCookieChoice, getCookieChoice } = require('../middleware/cookies/cookiesConsent'); 8 | const { renderA11yStatement } = require('../middleware/accessibility') 9 | const { renderSitemap } = require('../middleware/sitemap') 10 | 11 | 12 | const redirects = require('./redirects'); 13 | 14 | router.use(navigationDataLoader, getCookieChoice); 15 | 16 | router.post('/set-cookie-message', setCookieChoice); 17 | router.post('/cookie-policy', cookiePolicyPostHandler, renderCookiePolicy); 18 | 19 | router.get('/', (req, res) => { 20 | res.render('index'); 21 | }); 22 | 23 | // TODO this needs investigating as to why we redirect to /index on live? 24 | router.get('/index', (req, res) => { 25 | res.render('index'); 26 | }); 27 | 28 | router.get('/cookie-policy', renderCookiePolicy); 29 | router.get('/cookie-details', renderCookieDetails); 30 | router.get('/accessibility', renderA11yStatement); 31 | router.get('/sitemap', renderSitemap) 32 | 33 | // redirects 34 | router.use('/', redirects); 35 | 36 | module.exports = router; 37 | -------------------------------------------------------------------------------- /app/routes/redirects.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | 4 | router.get('/patterns/consent-to-cookies', (req, res) => { 5 | res.redirect(301, '/patterns/retired-patterns/consent-to-cookies'); 6 | }) 7 | 8 | module.exports = router; 9 | -------------------------------------------------------------------------------- /app/utils/content-loader.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | contentLoader(req, res, next) { 3 | const { backlogSections } = require('../../config/content/backlog-page.json'); 4 | res.locals.backlogSections = backlogSections; 5 | next(); 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /app/utils/file-helper.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const yaml = require('js-yaml'); 3 | const nunjucks = require('nunjucks'); 4 | const matter = require('gray-matter'); 5 | const beautify = require('js-beautify').html; 6 | const { removeWhitespace } = require('../utils/regexes') 7 | 8 | // This helper function gets the params for a components Nunjucks macro 9 | // from the component's .yaml file. 10 | exports.getMacroParams = path => { 11 | const file = fs.readFileSync(path, 'utf8'); 12 | return yaml.load(file).params; 13 | } 14 | 15 | // This helper function takes a path of a file and 16 | // returns the contents as string 17 | exports.getFileContents = (path) => { 18 | let fileContents; 19 | try { 20 | fileContents = fs.readFileSync(path); 21 | } catch (err) { 22 | if (err.code === 'ENOENT') { 23 | console.log(err.message); 24 | } else { 25 | throw err; 26 | } 27 | } 28 | return fileContents.toString(); 29 | }; 30 | 31 | // This helper function takes a path of a *.md.njk file and 32 | // returns the Nunjucks syntax inside that file without markdown data and imports 33 | exports.getNunjucksCode = (path) => { 34 | const fileContents = this.getFileContents(path); 35 | const parsedFile = matter(fileContents); 36 | return parsedFile.content; 37 | }; 38 | 39 | // This helper function takes a path of a *.md.njk file and 40 | // returns the HTML rendered by Nunjucks without markdown data 41 | exports.getHtmlCode = (path) => { 42 | const fileContents = this.getFileContents(path); 43 | const parsedFile = matter(fileContents); 44 | const { content } = parsedFile; 45 | let html; 46 | try { 47 | html = nunjucks.renderString(content); 48 | } catch (err) { 49 | if (err) { 50 | console.log(`Could not get HTML code from ${path}`); 51 | } 52 | } 53 | return beautify(html.replace(removeWhitespace,''), { 54 | end_with_newline: true, 55 | // If there are multiple blank lines, reduce down to one blank new line. 56 | max_preserve_newlines: 1, 57 | }); 58 | }; 59 | 60 | // returns CSS from path provided 61 | exports.getCSSCode = (path) => { 62 | let fileContents; 63 | try { 64 | const file = this.getFileContents(path); 65 | const parsedFile = matter(file); 66 | fileContents = beautify(parsedFile.content); 67 | } catch(err) { 68 | if(err){ 69 | return null; 70 | } 71 | } 72 | return fileContents; 73 | } -------------------------------------------------------------------------------- /app/utils/navigation-data-loader.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // Load JSON data and expose it to Nunjucks 3 | navigationDataLoader(req, res, next) { 4 | const { navItems } = require('../../config/navigation-data.json'); 5 | res.locals.navItems = navItems; 6 | next(); 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /app/utils/regexes.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | dotHtmlMatch: /\.html?$/i, 3 | slugMatch: /^\/([^.]+)$/, 4 | removeWhitespace: /^\s+|\s+$/gm 5 | }; -------------------------------------------------------------------------------- /app/views/_layouts/base.html: -------------------------------------------------------------------------------- 1 | {%- from "_macros/example/macro.njk" import dsExample -%} 2 | {%- from "_macros/mobile-navigation/macro.njk" import appMobileNavigation -%} {# TODO: shorten paths #} 3 | {%- from "_macros/navigation/macro.njk" import appNavigation -%} 4 | {%- from "_macros/sub-navigation/macro.njk" import appSubNavigation -%} 5 | {%- from "tag/macro.njk" import govukTag -%} 6 | {%- from "phase-banner/macro.njk" import govukPhaseBanner -%} 7 | {%- from "skip-link/macro.njk" import govukSkipLink -%} 8 | 9 | 10 | 11 | 12 | 22 | 23 | 24 | {{pageTitle}} - DWP Design System 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 45 | 46 | 47 | {% include "_cookie-banner.njk" %} 48 | {% block body %}{% endblock %} 49 | {% block bodyEnd %} 50 | {% block scripts %} 51 | {% include "scripts.html" %} 52 | {% block pageScripts %}{% endblock %} 53 | {% endblock %} 54 | {% endblock %} 55 | 56 | 57 | -------------------------------------------------------------------------------- /app/views/_layouts/code.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{pageTitle}} - DWP Design System 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | {% block body %} 18 |
19 | {% block pageContent %}{% endblock %} 20 |
21 | {% endblock %} 22 | {% include "scripts.html" %} 23 | {% block pageScripts %}{% endblock %} 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/views/_layouts/full-width.html: -------------------------------------------------------------------------------- 1 | 2 | {% extends "base.html" %} 3 | {% set navItems = { 4 | sectionId: sectionId, 5 | pageId: pageId, 6 | navItems: navItems, 7 | urlPartials: urlPartials 8 | } %} 9 | {% block body %} 10 | {% block skipLink %} 11 | {{ govukSkipLink({ 12 | href: '#main-content', 13 | text: 'Skip to main content' 14 | }) }} 15 | {% endblock %} 16 | {% block main %} 17 |
18 | {% include "_header.html" %} 19 | {{appMobileNavigation(navItems)}} 20 | {{appNavigation(navItems)}} 21 |
22 |
23 | {% block pageContent %}{% endblock %} 24 |
25 | {% endblock %} 26 |
27 | {% include "_footer.njk" %} 28 |
29 | {% endblock %} -------------------------------------------------------------------------------- /app/views/_layouts/sidebar-width.html: -------------------------------------------------------------------------------- 1 | 2 | {% extends "base.html" %} 3 | {% set navItems = { 4 | sectionId: sectionId, 5 | pageId: pageId, 6 | navItems: navItems, 7 | urlPartials: urlPartials 8 | } %} 9 | {% block body %} 10 | {% block skipLink %} 11 | {{ govukSkipLink({ 12 | href: '#main-content', 13 | text: 'Skip to main content' 14 | }) }} 15 | {% endblock %} 16 |
17 | {% include "_header.html" %} 18 | {{appMobileNavigation(navItems)}} 19 | {{appNavigation(navItems)}} 20 |
21 |
22 | {{appSubNavigation(navItems)}} 23 |
24 |
25 |
26 | {% block pageContent %}{% endblock %} 27 | {% block pageContentFoot %}{% endblock %} 28 |
29 |
30 | {% include "_back-to-top.njk" %} 31 |
32 | {% include "_footer.njk" %} 33 |
34 | {% endblock %} 35 | {% block pageScripts %} 36 | {% endblock %} -------------------------------------------------------------------------------- /app/views/_partials/_accessibility.njk: -------------------------------------------------------------------------------- 1 | 2 | {% extends "sidebar-width.html" %} 3 | {% set sectionId = "about-this-website" %} 4 | {% set pageTitle = "Accessibility" %} 5 | {% set pageId = "accessibility" %} 6 | 7 | {% block pageContent %} 8 | 9 |

Accessibility statement for the DWP Design System

10 |
11 |

This accessibility statement applies to the DWP Design System website at design-system.dwp.gov.uk.

12 |

This website is run by the Department for Work and Pensions (DWP). We want as many people as possible to be able to use this website. For example, that means you should be able to:

13 | 20 |

We’ve also made the website text as simple as possible to understand.

21 |

AbilityNet has advice on making your device easier to use if you have a disability.

22 |

How accessible this website is

23 |

We have tested the content of this website for accessibility using a range of browsers and technologies including screen readers. It meets the ‘AA’ standard of the Web Content Accessibility Guidelines version 2.1.

24 |

Reporting accessibility problems with this website

25 |

We’re always looking to improve the accessibility of this website. If you find any problems or think we’re not meeting accessibility requirements, contact the design system team on dwp-design-system@engineering.digital.dwp.gov.uk

26 |

Technical information about this website’s accessibility

27 |

DWP is committed to making its websites accessible, in accordance with the Public Sector Bodies (Websites and Mobile Applications) (No. 2) Accessibility Regulations 2018.

28 |

Compliance status

29 |

This website is fully compliant with the Web Content Accessibility Guidelines version 2.1 AA standard.

30 |

Feedback and contact information

31 |

If you need information on this website in a different format, email dwp-design-system@engineering.digital.dwp.gov.uk

32 |

Enforcement procedure

33 |

The Equality and Human Rights Commission (EHRC) is responsible for enforcing the Public Sector Bodies (Websites and Mobile Applications) (No. 2) Accessibility Regulations 2018 (the ‘accessibility regulations’). If you’re not happy with how we respond to your complaint, contact the Equality Advisory and Support Service (EASS).

34 |

Preparation of this accessibility statement

35 |

This statement was prepared on 23 June 2022. It was last reviewed on 23 June 2022.

36 |

This website was last tested on 1 October 2021. The test was carried out by the DWP Accessibility Standards and Strategy Team.

37 |
38 | 39 | {% endblock %} 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /app/views/_partials/_back-to-top.njk: -------------------------------------------------------------------------------- 1 |
2 | 3 | {#- The SVG needs `focusable="false"` so that Internet Explorer does not 4 | treat it as an interactive element - without this it will be 'focusable' 5 | when using the keyboard to navigate. #} 6 | 7 | 8 | Back to top 9 | 10 |
-------------------------------------------------------------------------------- /app/views/_partials/_component-index.njk: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |

Internal services footer

5 |

The internal services footer is a simplified standard footer for services used by DWP staff or agents.

6 |

View internal services footer component

7 |
8 | 9 |
10 |

Hint text

11 |

Hint text gives extra information that helps people to answer a question.

12 |

View hint text component

13 |
14 | 15 |
16 |

Key details bar

17 |

The key details bar groups and highlights the most relevant information on a page so that agents can find it easily.

18 |

View key details bar component

19 |
20 | 21 |
22 | -------------------------------------------------------------------------------- /app/views/_partials/_component-table.njk: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 |
List of components
NameGitHub discussionCode example
Internal services footer#90Yes
Hint text#88No
Internal services header#70Yes
Key details bar#160Yes
Timeline#67Yes
57 | -------------------------------------------------------------------------------- /app/views/_partials/_contact-panel.njk: -------------------------------------------------------------------------------- 1 |
2 |

Get in touch

3 |

4 | If you’ve got a question, idea or suggestion email the Design System team on 5 | 6 | dwp-design-system@engineering.digital.dwp.gov.uk 7 |

8 |
9 | -------------------------------------------------------------------------------- /app/views/_partials/_contribute-index.njk: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |

How to propose a component or pattern

5 |

Contribute ideas and get involved with the DWP Design System.

6 |

Find out how to get involved

7 |
8 | 9 |
10 |

Community backlog

11 |

See what people are currently working on in the community backlog.

12 |

View community backlog

13 |
14 | 15 |
16 |

GitHub Discussions

17 |

We're using GitHub Discussions to help the community talk to us about our components and patterns.

18 |

Join the discussion

19 |
20 | 21 |
22 | -------------------------------------------------------------------------------- /app/views/_partials/_cookie-policy.njk: -------------------------------------------------------------------------------- 1 | {% from "button/macro.njk" import govukButton %} 2 | {% from "fieldset/macro.njk" import govukFieldset %} 3 | {% from "radios/macro.njk" import govukRadios %} 4 | {% from "button/macro.njk" import govukButton %} 5 | {% from "error-summary/macro.njk" import govukErrorSummary %} 6 | 7 | 8 | {% extends "sidebar-width.html" %} 9 | {% set sectionId = "about-this-website" %} 10 | {% set pageTitle = "Cookie policy" %} 11 | {% set pageId = "cookie-policy" %} 12 | 13 | {% block pageContent %} 14 |
15 |
16 |
17 |
18 | 19 | {% if validationError %} 20 | {{ govukErrorSummary({ 21 | titleText: "There is a problem", 22 | errorList: [ 23 | { 24 | text: "Select a cookie option", 25 | href: "#cookie" 26 | } 27 | ] 28 | }) }} 29 | {% endif %} 30 | 31 |

How we use cookies

32 | 33 |
34 |

A cookie is a small file which is stored on your device for a short time to make this service work.

35 |

We use cookies that are:

36 |
    37 |
  • essential for the service to work, like remembering your answers to certain questions
  • 38 |
  • optional and will not stop the service from working, but will give us information to help us make it better
  • 39 |
40 |

We will not:

41 |
    42 |
  • use any essential cookies until you use the service
  • 43 |
  • use any optional cookies unless you tell us we can
  • 44 |
  • be able identify you through using cookies
  • 45 |
46 | 47 |

Optional cookie settings

48 |

Analytics cookies

49 |

We use Google Analytics to get information about how you use this service and help us make it better.

50 | 51 |
52 | {% if validationError %} 53 | {{ govukRadios({ 54 | classes: "govuk-radios--inline", 55 | idPrefix: "cookie", 56 | name: "cookieChoice", 57 | fieldset: { 58 | legend: { 59 | text: "Can we use cookies to help us improve the service?", 60 | classes: "govuk-fieldset__legend--s" 61 | } 62 | }, 63 | errorMessage: { 64 | text: "Select a cookie option" 65 | }, 66 | items: [ 67 | { 68 | text: "Yes", 69 | value: "accept" 70 | }, 71 | { 72 | text: "No", 73 | value: "reject" 74 | } 75 | ] 76 | }) }} 77 | {% else %} 78 | {{ govukRadios({ 79 | classes: "govuk-radios--inline", 80 | idPrefix: "cookie", 81 | name: "cookieChoice", 82 | fieldset: { 83 | legend: { 84 | text: "Can we use cookies to help us improve the service?", 85 | classes: "govuk-fieldset__legend--s" 86 | } 87 | }, 88 | items: [ 89 | { 90 | text: "Yes", 91 | value: "accept", 92 | checked: cookieChoice === "accept" 93 | }, 94 | { 95 | text: "No", 96 | value: "reject", 97 | checked: cookieChoice === "reject" 98 | } 99 | ] 100 | }) }} 101 | {% endif %} 102 | 103 | {{ govukButton({ 104 | text: "Save and continue" 105 | }) }} 106 |
107 | 108 | 109 |
110 |
111 |
112 |
113 |
114 | {% endblock %} 115 | -------------------------------------------------------------------------------- /app/views/_partials/_footer.njk: -------------------------------------------------------------------------------- 1 | {% from "internal-services-footer/macro.njk" import dwpFooter %} 2 | 3 | {{ dwpFooter({ 4 | classes: "app-footer app-footer--full", 5 | containerClasses: "app-width-container", 6 | meta: { 7 | visuallyHiddenTitle: "About this website", 8 | items: [ 9 | { 10 | href: "/accessibility", 11 | text: "Accessibility" 12 | }, 13 | { 14 | href: "/cookie-details", 15 | text: "Cookies" 16 | }, 17 | { 18 | href: "https://www.gov.uk/government/organisations/department-for-work-pensions/about/personal-information-charter", 19 | text: "Privacy" 20 | },{ 21 | href: "/sitemap", 22 | text: "Sitemap" 23 | } 24 | ] 25 | } 26 | }) }} 27 | -------------------------------------------------------------------------------- /app/views/_partials/_header.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 11 |
12 | 15 |
16 |
17 |
18 | -------------------------------------------------------------------------------- /app/views/_partials/_macros/backlog/macro.njk: -------------------------------------------------------------------------------- 1 | {% macro backlogPage(params) %} 2 | {%- include "./template.njk" -%} 3 | {% endmacro %} -------------------------------------------------------------------------------- /app/views/_partials/_macros/backlog/template.njk: -------------------------------------------------------------------------------- 1 | {% for section in params %} 2 |

{{section.title}}

3 | 10 | {% endfor %} 11 | -------------------------------------------------------------------------------- /app/views/_partials/_macros/example/README.md: -------------------------------------------------------------------------------- 1 | # Example -------------------------------------------------------------------------------- /app/views/_partials/_macros/example/macro.njk: -------------------------------------------------------------------------------- 1 | {% macro dsExample(params) %} 2 | {%- include "./template.njk" -%} 3 | {% endmacro %} 4 | -------------------------------------------------------------------------------- /app/views/_partials/_macros/mobile-navigation/macro.njk: -------------------------------------------------------------------------------- 1 | {% macro appMobileNavigation(params) %} 2 | {%- include "./template.njk" -%} 3 | {% endmacro %} 4 | -------------------------------------------------------------------------------- /app/views/_partials/_macros/mobile-navigation/template.njk: -------------------------------------------------------------------------------- 1 | 78 | -------------------------------------------------------------------------------- /app/views/_partials/_macros/navigation/macro.njk: -------------------------------------------------------------------------------- 1 | {% macro appNavigation(params) %} 2 | {%- include "./template.njk" -%} 3 | {% endmacro %} -------------------------------------------------------------------------------- /app/views/_partials/_macros/navigation/template.njk: -------------------------------------------------------------------------------- 1 | 25 | -------------------------------------------------------------------------------- /app/views/_partials/_macros/sub-navigation/macro.njk: -------------------------------------------------------------------------------- 1 | {% macro appSubNavigation(params) %} 2 | {%- include "./template.njk" -%} 3 | {% endmacro %} 4 | -------------------------------------------------------------------------------- /app/views/_partials/_macros/sub-navigation/template.njk: -------------------------------------------------------------------------------- 1 | 45 | -------------------------------------------------------------------------------- /app/views/_partials/_page-not-found.njk: -------------------------------------------------------------------------------- 1 | {% extends "full-width.html" %} 2 | 3 | {% set pageTitle = "Page not found" %} 4 | 5 | {% block pageContent %} 6 |
7 |
8 |
9 |
10 |

Page not found

11 |

12 | If you typed the web address, check it is correct. 13 |

14 |

15 | If you pasted the web address, check you copied the entire address. 16 |

17 |

18 | Something broken? Please raise a new issue on GitHub using the ‘Bug report’ template, or email the design system team on dwp-design-system@engineering.digital.dwp.gov.uk. 19 | 20 |

21 |
22 |
23 |
24 |
25 | {% endblock %} -------------------------------------------------------------------------------- /app/views/_partials/_pattern-index.njk: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |

Add another thing

5 |

Help users to add more than one thing of the same type.

6 |

View Add another thing pattern

7 |
8 | 9 |
10 |

Toggle to Welsh

11 |

This pattern lets the user change the language used in a service from English to Welsh and from Welsh to English.

12 |

View toggle to Welsh pattern

13 |
14 | 15 |
16 |

Manage session timeout

17 |

Use this pattern to warn users that their session is about to end and explain what has happened after the session has timed out.

18 |

View session timeout pattern

19 |
20 | 21 |
22 | -------------------------------------------------------------------------------- /app/views/_partials/_pattern-table.njk: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
List of patterns
NameGitHub discussionCode example
Add another thing#87Yes
Make a declaration#69Yes
Manage a session timeout#66Yes
Toggle to Welsh#72Yes
49 | -------------------------------------------------------------------------------- /app/views/_partials/_sitemap.njk: -------------------------------------------------------------------------------- 1 | 2 | {% extends "sidebar-width.html" %} 3 | {% set sectionId = "about-this-website" %} 4 | {% set pageTitle = "Sitemap" %} 5 | {% set pageId = "sitemap" %} 6 | 7 | {% block pageContent %} 8 | 9 |

Sitemap

10 |
11 | 12 |

Get started

13 |

HTML and CSS

14 |

Installing using npm

15 | 16 |

Components

17 |

Hint text

18 |

Internal services footer

19 |

Internal services header

20 |

Key details bar

21 |

Timeline

22 | 23 | 24 |

Patterns

25 |

Help users to...

26 |

Add another thing

27 |

Add another thing: Example

28 |

Make a declaration

29 |

Manage a session timeout

30 |

Toggle to Welsh

31 |

Retired patterns

32 |

Consent to cookies

33 | 34 |

Community

35 |

Latest updates

36 |

Roadmap

37 |

Backlog

38 |

Contribute

39 |

The team

40 |
41 | 42 | {% endblock %} 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /app/views/_partials/scripts.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/views/community/README.md: -------------------------------------------------------------------------------- 1 | # Community 2 | The DWP Design System is for everyone. It brings together the latest research, design and development to make sure it is representative and relevant for its users. 3 | 4 | This depends on people sharing their research and experiences of the elements in use. Please tell us when you use something from the Design System by [contributing to the community backlog on GitHub](https://github.com/dwp/design-system-community-backlog/issues) or getting in touch with [the Design System team](/community/team). 5 | 6 | - [Latest updates](/community/latest-updates) – New patterns and components and changes to the Design System website. 7 | - [Roadmap](/community/roadmap) – Our plans for developing the Design System. 8 | - [Backlog](/community/backlog) – Patterns and components we'll be working on next. 9 | - [Contribute](/community/contribute) – Contribute to the Design System by proposing something new, improving an existing thing or sharing your research. 10 | - [The team](/community/team) – Who we are. -------------------------------------------------------------------------------- /app/views/community/backlog/README.md: -------------------------------------------------------------------------------- 1 | # Backlog 2 | 3 | The DWP Design System is built upon the research and experience of teams across DWP. 4 | 5 | Anyone can propose, develop or contribute to new patterns and components, or suggest improvements to existing ones. 6 | 7 | Here is a list of the components, patterns and updates currently on the [DWP Design System Community Backlog](https://github.com/dwp/design-system-community-backlog/projects/1). They can be: 8 | - **In progress** – someone is working on the component or pattern 9 | - **To do** – the proposed component or pattern has been agreed and is ready to work on 10 | - **Proposed** – someone has suggested a new component or pattern 11 | 12 | -------------------------------------------------------------------------------- /app/views/community/backlog/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "community" %} 4 | {% set pageTitle = "Backlog" %} 5 | {% set pageId = "backlog" %} 6 | 7 | {%- from "../../_partials/_macros/backlog/macro.njk" import backlogPage -%} 8 | 9 | {% block pageContent %} 10 | {% markdown %}{% include "./README.md" %}{% endmarkdown %} 11 | {{backlogPage(backlogSections)}} 12 | {% endblock %} 13 | 14 | {% block pageContentFoot %} 15 |
16 | {% include "_contact-panel.njk" %} 17 |
18 | {% endblock %} -------------------------------------------------------------------------------- /app/views/community/contribute/README.md: -------------------------------------------------------------------------------- 1 | # Contribute 2 | 3 | Anyone can contribute to the Design System by proposing a new component or pattern, helping to develop an existing component or pattern or adding research insights to existing components or patterns. 4 | 5 | Before you start, check the [GOV.UK Design System](https://design-system.service.gov.uk/) and the [DWP Design System Community Backlog](https://github.com/dwp/design-system-community-backlog/issues) to see if your idea has already been suggested. 6 | 7 | ## To help develop a proposed pattern 8 | - If your idea is already on the backlog, follow the link from the [backlog page](/community/backlog) to its GitHub issue or discussion. 9 | - Add your comments, feedback or examples of the component or pattern in use. 10 | - The Design System team will get in touch to talk through your findings and discuss if more work is needed. 11 | 12 | 13 | ## To propose a new component or pattern 14 | - If your idea is not on the backlog, you can [create a new backlog item in GitHub](https://github.com/dwp/design-system-community-backlog/issues/new). Tell us why you need the component or pattern and share any examples or evidence you have to support the proposal. 15 | - The Design System team will be in contact with you to help with the development of the new component or pattern. 16 | 17 | 18 | ## To contribute to a published component or pattern 19 | 20 | - Follow the link from the component or pattern page to its GitHub issue or discussion. 21 | - Add your comments, feedback or examples of the component or pattern in use. 22 | - The Design System team will be in contact with you to talk through your findings and discuss if more work is needed. 23 | 24 | 25 | ## DWP Design Examples 26 | 27 | [DWP Design Examples](https://dwpdigital.atlassian.net/wiki/spaces/INTD/pages/131921347136/DWP+Design+Examples) (opens in Confluence) is a reference tool run by the DWP Interaction Design community. It includes interaction flows, components and patterns designers across DWP are working on to help solve user needs. Each design includes examples of its use and any research that has been gathered. 28 | -------------------------------------------------------------------------------- /app/views/community/contribute/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "community" %} 4 | {% set pageTitle = "Contribute" %} 5 | {% set pageId = "contribute" %} 6 | 7 | {% block pageContent %} 8 | {% markdown %}{% include "./README.md" %}{% endmarkdown %} 9 | {% include "_contact-panel.njk" %} 10 | {% endblock %} -------------------------------------------------------------------------------- /app/views/community/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "community" %} 4 | {% set pageTitle = "Community" %} 5 | {% set pageId = "community" %} 6 | 7 | {% block pageContent %} 8 | {% markdown %}{% include "./README.md" %}{% endmarkdown %} 9 | {% include "_contact-panel.njk" %} 10 | {% endblock %} -------------------------------------------------------------------------------- /app/views/community/latest-updates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "community" %} 4 | {% set pageTitle = "Latest updates" %} 5 | {% set pageId = "latest-updates" %} 6 | 7 | {% block pageContent %} 8 | {% markdown %}{% include "./README.md" %}{% endmarkdown %} 9 | {% include "_contact-panel.njk" %} 10 | {% endblock %} -------------------------------------------------------------------------------- /app/views/community/roadmap/README.md: -------------------------------------------------------------------------------- 1 | # Roadmap 2 | 3 | This is the roadmap for the DWP Design System. It shows what we plan to work on in the future. We update this plan regularly depending on the feedback, contributions and requests we receive. 4 | 5 | The roadmap was last updated in February 2022. See the [latest updates](/community/latest-updates) section for previously released features. 6 | 7 | ## Now 8 | ### Design System goals 9 | 1. To publish at least 4 priority components or patterns before May 2022. We will publish: 10 | - [Get help with an application or service](https://github.com/dwp/design-system-community-backlog/issues/23) 11 | - [Find my address by postcode/house number](https://github.com/dwp/design-system-community-backlog/issues/8) 12 | - [Add another thing (done)](/patterns/add-another-thing) 13 | - [Navigation (primary)](https://github.com/dwp/design-system-community-backlog/issues/25) 14 | - [Hint text (done)](/components/hint-text) 15 | 2. To run discovery and research activity on: 16 | - [Contact preferences](https://github.com/dwp/design-system/issues/244) – help us by joining the [Contact preferences discussion](https://github.com/dwp/design-system-community-backlog/issues/51) 17 | - [Navigation (secondary/pagination/tabs)](https://github.com/dwp/design-system/issues/176) – help us by joining the [Navigation discussion](https://github.com/dwp/design-system-community-backlog/issues/25) 18 | - [Find someone](https://github.com/dwp/design-system/issues/245) – help us by joining the [Find someone discussion](https://github.com/dwp/design-system-community-backlog/issues/31) 19 | - [Find a record](https://github.com/dwp/design-system/issues/249) – help us by joining the [Find a record discussion](https://github.com/dwp/design-system-community-backlog/issues/27) 20 | 3. To make it easier for people to see what's been worked on, what's new and how to use it. To do this we will: 21 | - [publish Backlog (done)](/community/backlog) 22 | - [publish Roadmap (done)](/community/roadmap) 23 | - [publish 'Get started' guidance (ongoing)](https://github.com/dwp/design-system/issues/216) 24 | - [publish latest updates section (ongoing)](/community/latest-updates) 25 | 4. To make sure the Design System website and published things meet WCAG 2.1 by: 26 | - [publishing Accessibility Statement](https://github.com/dwp/design-system/issues/170) 27 | - [publishing the results of accessibility testing on each component](https://github.com/dwp/design-system/issues/170) 28 | 29 |
30 | 31 | ## Next 32 | - [Discovery on filters and search components](https://github.com/dwp/design-system/issues/179) 33 | 34 | You can view the full [DWP Design System roadmap](https://github.com/dwp/design-system/projects/3) on GitHub. 35 | 36 |
37 | -------------------------------------------------------------------------------- /app/views/community/roadmap/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "community" %} 4 | {% set pageTitle = "Roadmap" %} 5 | {% set pageId = "roadmap" %} 6 | 7 | {% block pageContent %} 8 | {% markdown %}{% include "./README.md" %}{% endmarkdown %} 9 | {% include "_contact-panel.njk" %} 10 | {% endblock %} -------------------------------------------------------------------------------- /app/views/community/team/README.md: -------------------------------------------------------------------------------- 1 | # The team 2 | 3 | If you’ve got a question, idea or suggestion email the Design System team on [dwp-design-system@engineering.digital.dwp.gov.uk](mailto:dwp-design-system@engineering.digital.dwp.gov.uk). -------------------------------------------------------------------------------- /app/views/community/team/_team-daniella.njk: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |
7 |

Daniella Taylor – Development

8 | 16 | 17 |
18 |
19 |
20 | -------------------------------------------------------------------------------- /app/views/community/team/_team-helen.njk: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |
7 |

Helen Osgerby – Content Design

8 | 16 |

Things I'm working on this sprint:

17 |
    18 |
  • 19 | Toggle to Welsh pattern 20 |
  • 21 | Key details bar component 22 | 23 |
  • 24 | Internal services header component 25 |
  • 26 |
27 |
28 |
29 |
30 | -------------------------------------------------------------------------------- /app/views/community/team/_team-jon.njk: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |
7 |

Jon Hurrell – Lead

8 | 16 | 17 |
18 |
19 |
20 | -------------------------------------------------------------------------------- /app/views/community/team/_team-martin.njk: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |
7 |

Martin Wake – Content Design (interim)

8 | 16 |
17 |
18 |
19 | -------------------------------------------------------------------------------- /app/views/community/team/_team-mitz.njk: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |
7 |

Mitz Lad – Interaction Design (interim)

8 | 16 |
17 |
18 |
19 | -------------------------------------------------------------------------------- /app/views/community/team/_team-simone.njk: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |
7 |

Simone Duca – Development

8 | 16 | 17 |
18 |
19 |
20 | -------------------------------------------------------------------------------- /app/views/community/team/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "community" %} 4 | {% set pageTitle = "The team" %} 5 | {% set pageId = "team" %} 6 | 7 | {% block pageContent %} 8 | 9 | {% markdown %}{% include "./README.md" %}{% endmarkdown %} 10 | {% include "./_team-simone.njk" %} 11 | {% include "./_team-jon.njk" %} 12 | {% include "./_team-mitz.njk" %} 13 | {% include "./_team-daniella.njk" %} 14 | {% include "./_team-martin.njk" %} 15 | 16 |
17 | {% include "_contact-panel.njk" %} 18 |
19 | 20 | {% endblock %} -------------------------------------------------------------------------------- /app/views/components/README.md: -------------------------------------------------------------------------------- 1 | # Components 2 | 3 | Components are reusable parts of the user interface that designers across DWP have made to support a variety of applications. 4 | 5 | Individual components can be used in multiple different [patterns](/patterns) and contexts. For example, the [timeline](/components/timeline) component can be used at the side of the page or on a page of its own. 6 | 7 | These components should be used in addition to those in the GOV.UK Design System. We will share the design and research of these components with the GOV.UK Design System so they can be used more widely. 8 | 9 | -------------------------------------------------------------------------------- /app/views/components/hint-text/examples/default/index.html: -------------------------------------------------------------------------------- 1 | {% extends "code.html" %} 2 | 3 | {% set pageTitle = "Timeline" %} 4 | 5 | {% block pageContent %} 6 | {% include './template.html' %} 7 | {% endblock %} -------------------------------------------------------------------------------- /app/views/components/hint-text/examples/default/styles.css: -------------------------------------------------------------------------------- 1 | .dwp-timeline { 2 | font-family: Arial, sans-serif; 3 | border-left: 3px solid #1d70b8; 4 | list-style-type: none; 5 | padding: 0; 6 | } 7 | 8 | .dwp-timeline__entry { 9 | margin: 2em 0; 10 | padding-left: 1.125em; 11 | position: relative; 12 | top: -.6em; 13 | } 14 | 15 | .dwp-timeline__entry::before { 16 | background-color: #1d70b8; 17 | content: ''; 18 | height: 3px; 19 | left: 0; 20 | position: absolute; 21 | top: .6em; 22 | width: 10px; 23 | } -------------------------------------------------------------------------------- /app/views/components/hint-text/examples/default/template.html: -------------------------------------------------------------------------------- 1 | {% from "timeline/macro.njk" import dwpTimeline %} 2 | 3 |
4 | {{ dwpTimeline({ 5 | title: "Appointments", 6 | events: [ 7 | { 8 | name: "John Smith", 9 | state: "Accepted", 10 | date: "11 Aug 2021" 11 | }, 12 | { 13 | name: "John Smith", 14 | state: "Declined", 15 | date: "10 Aug 2021" 16 | } 17 | ] 18 | }) }} 19 |
20 | 21 | -------------------------------------------------------------------------------- /app/views/components/hint-text/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "components" %} 4 | {% set pageTitle = "Hint text" %} 5 | {% set pageId = "hint-text" %} 6 | 7 | {% block pageContent %} 8 |

Components {{pageTitle}}

9 | 10 |
11 | {% markdown %}{% include "./README.md.njk" %}{% endmarkdown %} 12 |
13 |
14 | {% include "_contact-panel.njk" %} 15 |
16 | {% endblock %} -------------------------------------------------------------------------------- /app/views/components/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "components" %} 4 | {% set pageTitle = "Components" %} 5 | {% set pageId = "components" %} 6 | 7 | {% block pageContent %} 8 | {% markdown %}{% include "./README.md" %}{% endmarkdown %} 9 | {% include "_component-table.njk" %} 10 | {% endblock %} 11 | 12 | {% block pageContentFoot %} 13 |

See all the components in the backlog

16 | {% endblock %} -------------------------------------------------------------------------------- /app/views/components/internal-services-footer/README.md.njk: -------------------------------------------------------------------------------- 1 | The internal services footer is based on the standard GOV.UK footer component but with the copyright notice and Royal Coat of Arms removed. 2 | 3 | You may also want to read our step-by-step guidance on [adapting the GOV.UK Prototype Kit for use with internal services](https://github.com/dwp/design-system/discussions/347), including changing the default font and removing other branding elements. 4 | 5 | ## When to use this component 6 | Use this footer for internal services not hosted on service.gov.uk domains. Users of these services will normally be DWP staff but may also include staff of other organisations such as local authorities. 7 | 8 | ## When not to use this component 9 | If your service is hosted on a service.gov.uk domain it should use the [GOV.UK Design System footer component](https://design-system.service.gov.uk/components/footer/). 10 | 11 | ## How it works 12 | Like the GOV.UK footer, the internal services footer can be adapted to the needs of your service. When deciding what information to place in the footer, remember that: 13 | - information placed in the footer is sometimes skipped or not noticed 14 | - the grey background lowers the contrast ratio which will limit readability for some people 15 | 16 | ### Footer with links 17 | {{dsExample({ 18 | name: 'internal-services-footer', 19 | example: 'meta-links', 20 | height: 140 21 | })}} 22 | 23 | ### Footer with secondary navigation 24 | {{dsExample({ 25 | name: 'internal-services-footer', 26 | example: 'default', 27 | height: 140 28 | })}} 29 | 30 | ### Footer with links, secondary navigation and plain text 31 | {{dsExample({ 32 | name: 'internal-services-footer', 33 | example: 'nav-and-links', 34 | height: 140 35 | })}} 36 | 37 | ## Research 38 | 39 | ### Have you used this component? 40 | Please let us know what you found so we can make it better for everyone. There is an [open discussion for this component on GitHub](https://github.com/dwp/design-system-community-backlog/discussions/90) where you can share anything you think might be useful. 41 | 42 | [Discuss Internal services footer on GitHub](https://github.com/dwp/design-system-community-backlog/discussions/90) 43 | 44 | -------------------------------------------------------------------------------- /app/views/components/internal-services-footer/examples/default/index.html: -------------------------------------------------------------------------------- 1 | {% extends "code.html" %} 2 | 3 | {% set pageTitle = "Internal Services Footer" %} 4 | 5 | {% block pageContent %} 6 | {% include './template.html' %} 7 | {% endblock %} -------------------------------------------------------------------------------- /app/views/components/internal-services-footer/examples/default/template.html: -------------------------------------------------------------------------------- 1 | {% from "internal-services-footer/macro.njk" import dwpFooter %} 2 | 3 | {{ dwpFooter({ 4 | navigation: [ 5 | { 6 | title: "Two column list", 7 | width: "two-thirds", 8 | columns: 2, 9 | items: [ 10 | { 11 | text: "Item 1", 12 | href: "#1" 13 | }, 14 | { 15 | text: "Item 2", 16 | href: "#2" 17 | }, 18 | { 19 | text: "Item 3", 20 | href: "#3" 21 | }, 22 | { 23 | text: "Item 4", 24 | href: "#4" 25 | }, 26 | { 27 | text: "Item 5", 28 | href: "#5" 29 | }, 30 | { 31 | text: "Item 6", 32 | href: "#6" 33 | } 34 | ] 35 | }, 36 | { 37 | title: "One column list", 38 | width: "one-third", 39 | items: [ 40 | { 41 | text: "Item 1", 42 | href: "#1" 43 | }, 44 | { 45 | text: "Item 2", 46 | href: "#2" 47 | }, 48 | { 49 | text: "Item 3", 50 | href: "#3" 51 | } 52 | ] 53 | } 54 | ] 55 | }) }} 56 | -------------------------------------------------------------------------------- /app/views/components/internal-services-footer/examples/meta-links/index.html: -------------------------------------------------------------------------------- 1 | {% extends "code.html" %} 2 | 3 | {% set pageTitle = "Internal Services Footer" %} 4 | 5 | {% block pageContent %} 6 | {% include './template.html' %} 7 | {% endblock %} -------------------------------------------------------------------------------- /app/views/components/internal-services-footer/examples/meta-links/template.html: -------------------------------------------------------------------------------- 1 | {% from "internal-services-footer/macro.njk" import dwpFooter %} 2 | 3 | {{ dwpFooter({ 4 | meta: { 5 | visuallyHiddenTitle: "Meta links", 6 | items: [ 7 | { 8 | href: "#1", 9 | text: "Item 1" 10 | }, 11 | { 12 | href: "#2", 13 | text: "Item 2" 14 | }, 15 | { 16 | href: "#3", 17 | text: "Item 3" 18 | } 19 | ] 20 | } 21 | }) }} 22 | -------------------------------------------------------------------------------- /app/views/components/internal-services-footer/examples/nav-and-links/index.html: -------------------------------------------------------------------------------- 1 | {% extends "code.html" %} 2 | 3 | {% set pageTitle = "Internal Services Footer" %} 4 | 5 | {% block pageContent %} 6 | {% include './template.html' %} 7 | {% endblock %} -------------------------------------------------------------------------------- /app/views/components/internal-services-footer/examples/nav-and-links/template.html: -------------------------------------------------------------------------------- 1 | {% from "internal-services-footer/macro.njk" import dwpFooter %} 2 | 3 | {{ dwpFooter({ 4 | navigation: [ 5 | { 6 | title: "Two column list", 7 | width: "two-thirds", 8 | columns: 2, 9 | items: [ 10 | { 11 | text: "Item 1", 12 | href: "#1" 13 | }, 14 | { 15 | text: "Item 2", 16 | href: "#2" 17 | }, 18 | { 19 | text: "Item 3", 20 | href: "#3" 21 | }, 22 | { 23 | text: "Item 4", 24 | href: "#4" 25 | }, 26 | { 27 | text: "Item 5", 28 | href: "#5" 29 | }, 30 | { 31 | text: "Item 6", 32 | href: "#6" 33 | } 34 | ] 35 | }, 36 | { 37 | title: "One column list", 38 | width: "one-third", 39 | items: [ 40 | { 41 | text: "Item 1", 42 | href: "#1" 43 | }, 44 | { 45 | text: "Item 2", 46 | href: "#2" 47 | }, 48 | { 49 | text: "Item 3", 50 | href: "#3" 51 | } 52 | ] 53 | } 54 | ], 55 | meta: { 56 | visuallyHiddenTitle: "Meta links", 57 | items: [ 58 | { 59 | href: "#1", 60 | text: "Item 1" 61 | }, 62 | { 63 | href: "#2", 64 | text: "Item 2" 65 | }, 66 | { 67 | href: "#3", 68 | text: "Item 3" 69 | } 70 | ], 71 | text: "Plain text item" 72 | } 73 | }) }} 74 | -------------------------------------------------------------------------------- /app/views/components/internal-services-footer/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "components" %} 4 | {% set pageTitle = "Internal services footer" %} 5 | {% set pageId = "internal-services-footer" %} 6 | 7 | {% block pageContent %} 8 |

Components {{pageTitle}}

9 | 10 | {% markdown %}{% include "./README.md.njk" %}{% endmarkdown %} 11 | 12 |
13 | {% include "_contact-panel.njk" %} 14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /app/views/components/internal-services-header/README.md.njk: -------------------------------------------------------------------------------- 1 | The internal services header shows users what service or system they are using. 2 | 3 | {{dsExample({ 4 | name: 'internal-services-header', 5 | description: 'Internal services header', 6 | example: 'default', 7 | height: 140 8 | })}} 9 | 10 | ## When to use this component 11 | 12 | Use this header for any service or system not on GOV.UK, such as internal and agent-facing services. 13 | 14 | ## When not to use this component 15 | 16 | If the service is hosted on a service.gov.uk domain it should use the GOV.UK Design System Header component. 17 | 18 | ## How it works 19 | 20 | The name of the service should be left-aligned in the header. 21 | 22 | If your users can sign in or out of a service you should include a link for them to do this on the right-hand side of the header. 23 | 24 | {{dsExample({ 25 | name: 'internal-services-header', 26 | description: 'Internal services header when signed in', 27 | example: 'signin', 28 | height: 140 29 | })}} 30 | 31 | ## Research on this component 32 | 33 | This component has been used on services across DWP, including 34 | 35 | 39 | 40 | The internal services header has only been researched on agent-facing services. More research is needed on the component. 41 | 42 | You can help to improve this pattern by: 43 | 44 | 50 | 51 | -------------------------------------------------------------------------------- /app/views/components/internal-services-header/examples/default/index.html: -------------------------------------------------------------------------------- 1 | {% extends "code.html" %} 2 | 3 | {% set pageTitle = "Internal Header" %} 4 | 5 | {% block pageContent %} 6 | {% include './template.html' %} 7 | {% endblock %} -------------------------------------------------------------------------------- /app/views/components/internal-services-header/examples/default/styles.css: -------------------------------------------------------------------------------- 1 | .dwp-header { 2 | background-color: #0b0c0c; 3 | border-bottom: 0; 4 | width: 100%; 5 | } 6 | 7 | .dwp-header__container { 8 | border-bottom: 0; 9 | padding: 10px 30px 0; 10 | display: flex; 11 | } 12 | 13 | @media (max-width: 40.0525em) { 14 | .dwp-header__container { 15 | padding: 10px 15px 0; 16 | } 17 | } 18 | 19 | .dwp-header__container--service-name { 20 | width: 66.66%; 21 | } 22 | 23 | .dwp-header__container--action { 24 | width: 33.33%; 25 | } 26 | 27 | .dwp-header__container--action .action { 28 | float: right; 29 | font-weight: 700; 30 | margin-top: 2px; 31 | } 32 | 33 | @media (min-width: 40.0625em) { 34 | .dwp-header__container--action .action { 35 | margin-top: 5px; 36 | } 37 | } -------------------------------------------------------------------------------- /app/views/components/internal-services-header/examples/default/template.html: -------------------------------------------------------------------------------- 1 | {% from "internal-services-header/macro.njk" import dwpHeader %} 2 | 3 | {{ dwpHeader({ 4 | name: "Apply for a benefit", 5 | serviceHref: '#', 6 | container:true 7 | }) }} 8 | -------------------------------------------------------------------------------- /app/views/components/internal-services-header/examples/signin/index.html: -------------------------------------------------------------------------------- 1 | {% extends "code.html" %} 2 | 3 | {% set pageTitle = "Internal Header" %} 4 | 5 | {% block pageContent %} 6 | {% include './template.html' %} 7 | {% endblock %} -------------------------------------------------------------------------------- /app/views/components/internal-services-header/examples/signin/styles.css: -------------------------------------------------------------------------------- 1 | .dwp-header { 2 | background-color: #0b0c0c; 3 | border-bottom: 0; 4 | width: 100%; 5 | } 6 | 7 | .dwp-header__container { 8 | margin-bottom: 0; 9 | border-bottom: 0; 10 | } 11 | 12 | .dwp-header__container--service-name { 13 | width: 66.66%; 14 | float: left; 15 | } 16 | 17 | .dwp-header__container--sign-in { 18 | width: 33.33%; 19 | float: right; 20 | } 21 | 22 | .sign-in { 23 | float: right; 24 | font-weight: 700; 25 | margin-top: 2px; 26 | } 27 | 28 | @media (min-width: 40.0625em) { 29 | .sign-in { 30 | margin-top: 5px; 31 | } 32 | } -------------------------------------------------------------------------------- /app/views/components/internal-services-header/examples/signin/template.html: -------------------------------------------------------------------------------- 1 | {% from "internal-services-header/macro.njk" import dwpHeader %} 2 | 3 | {{ dwpHeader({ 4 | name: "Apply for a benefit", 5 | serviceHref: "#", 6 | action: "Sign out", 7 | actionHref: "#", 8 | container:true 9 | }) }} 10 | 11 | -------------------------------------------------------------------------------- /app/views/components/internal-services-header/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "components" %} 4 | {% set pageTitle = "Internal services header" %} 5 | {% set pageId = "internal-services-header" %} 6 | 7 | {% block pageContent %} 8 |

Components {{pageTitle}}

9 | 10 | {% markdown %}{% include "./README.md.njk" %}{% endmarkdown %} 11 | 12 |
13 | {% include "_contact-panel.njk" %} 14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /app/views/components/key-details-bar/README.md.njk: -------------------------------------------------------------------------------- 1 | The key details bar groups and highlights the most relevant information on a page so that agents can find it easily. 2 | 3 | It has only been researched on agent-facing services. 4 | 5 | ## When to use this component 6 | 7 | Use the key details bar when there is a small set of information that users check before starting a task or refer to while doing it. 8 | 9 | Examples of key details could include: 10 | 19 | 20 | 21 | ## When not to use this component 22 | 23 | Too much text will make this component hard to use, especially on smaller screens. Before using this component always check it on a range of screen sizes, including mobile devices. 24 | 25 | If you need to highlight more information than can be usefully shown in the key details bar on a mobile device, use a different solution. 26 | 27 | ## How it works 28 | 29 | {{dsExample({ 30 | name: 'key-details-bar', 31 | description: 'Key details bar', 32 | example: 'default', 33 | height: 200 34 | })}} 35 | 36 | The key details bar has a top block for the first and second most important items, and an optional bottom block for other key details. 37 | 38 | You should use: 39 | 40 | 44 | 45 | In the top block, do not use the same style for multiple items. 46 | 47 | ### Using status tags 48 | 49 | You can use the [tag component from the GOV.UK Design System](https://design-system.service.gov.uk/components/tag/) in the key details bar when something can have more than one status and it’s useful to the user to know that status. 50 | 51 | ## Technical details 52 | 53 | The key details bar should be placed outside the `
` tag. This will allow a screen reader user to skip past it using the skip link. 54 | 55 | You may need your `

` to reference something from the key details bar so that it still makes sense when a screen reader user skips the bar. This may be required even if your `

` is visually hidden. 56 | 57 | ## Research on this component 58 | This component has only been researched on agent-facing services. 59 | 60 | ## Services using this component 61 | This is an updated version of a component used in several DWP services: 62 | 63 | 68 | 69 | ## Help us improve this component 70 | You can help to improve this component by: 71 | 72 | 78 | -------------------------------------------------------------------------------- /app/views/components/key-details-bar/examples/default/index.html: -------------------------------------------------------------------------------- 1 | {% extends "code.html" %} 2 | 3 | {% set pageTitle = "Key details bar" %} 4 | 5 | {% block pageContent %} 6 | {% include './template.html' %} 7 | {% endblock %} -------------------------------------------------------------------------------- /app/views/components/key-details-bar/examples/default/styles.css: -------------------------------------------------------------------------------- 1 | .dwp-key-details-bar { 2 | background-color: #1d70b8; 3 | color: #fff; 4 | font-family: Arial, sans-serif; 5 | } 6 | 7 | .dwp-key-details-bar dt, 8 | .dwp-key-details-bar dd, { 9 | border: none; 10 | margin: 0; 11 | padding: 0; 12 | } 13 | 14 | .dwp-key-details-bar .dwp-key-details-bar__key-details { 15 | margin: 0 auto; 16 | max-width: 960px; 17 | padding: 20px 30px; 18 | position: relative; 19 | } 20 | 21 | .dwp-key-details-bar .dwp-key-details-bar__key-details .dwp-key-details-bar__top-block::after, 22 | .dwp-key-details-bar .dwp-key-details-bar__key-details .dwp-key-details-bar__bottom-block::after { 23 | clear: both; 24 | content: ' '; 25 | display: block; 26 | } 27 | 28 | .dwp-key-details-bar .dwp-key-details-bar__key-details .dwp-key-details-bar__bottom-block { 29 | border-top: 1px solid rgba(255, 255, 255, .3); 30 | content: ' '; 31 | padding-top: 10px; 32 | margin-top: 6px; 33 | } 34 | 35 | .dwp-key-details-bar .dwp-key-details-bar__key-details dd, 36 | .dwp-key-details-bar .dwp-key-details-bar__key-details dt { 37 | float: left; 38 | font-size: 19px; 39 | margin-right: 5px; 40 | } 41 | 42 | .dwp-key-details-bar .dwp-key-details-bar__key-details dd { 43 | margin-right: 20px; 44 | } 45 | 46 | .dwp-key-details-bar .dwp-key-details-bar__key-details .dwp-key-details-bar__name { 47 | font-size: 36px; 48 | font-weight: 700; 49 | line-height: 1.11111; 50 | margin-right: 10px; 51 | } 52 | 53 | .dwp-key-details-bar .dwp-key-details-bar__key-details .dwp-key-details-bar__nino { 54 | font-size: 24px; 55 | line-height: 1; 56 | margin-top: 12px; 57 | } 58 | 59 | .dwp-key-details-bar .dwp-key-details-bar__key-details .dwp-key-details-bar__status { 60 | font-size: 16px; 61 | font-weight: 700; 62 | line-height: 1.25; 63 | padding: 5px 8px 0; 64 | color: #005ea5; 65 | background-color: #fff; 66 | letter-spacing: 1px; 67 | text-decoration: none; 68 | text-transform: uppercase; 69 | float: right; 70 | margin: 5px 0 0; 71 | } 72 | 73 | @media (max-width: 40.0525em) { 74 | .dwp-key-details-bar .dwp-key-details-bar__key-details { 75 | padding: 20px 15px; 76 | } 77 | 78 | .dwp-key-details-bar .dwp-key-details-bar__key-details .dwp-key-details-bar__bottom-block { 79 | border: 0; 80 | } 81 | 82 | .dwp-key-details-bar .dwp-key-details-bar__key-details dd, 83 | .dwp-key-details-bar .dwp-key-details-bar__key-details dt { 84 | float: none; 85 | font-size: 16px; 86 | margin: 0; 87 | } 88 | 89 | .dwp-key-details-bar .dwp-key-details-bar__key-details dd { 90 | margin-bottom: 20px; 91 | } 92 | 93 | .dwp-key-details-bar .dwp-key-details-bar__key-details dd:last-of-type { 94 | margin-bottom: 20px; 95 | } 96 | 97 | .dwp-key-details-bar .dwp-key-details-bar__key-details .dwp-key-details-bar__name { 98 | font-size: 24px; 99 | line-height: 1.04167; 100 | float: left; 101 | margin: 0 5px 0 0; 102 | } 103 | 104 | .dwp-key-details-bar .dwp-key-details-bar__key-details .dwp-key-details-bar__nino { 105 | font-size: 18px; 106 | float: left; 107 | margin: 5px 0 0 0; 108 | } 109 | 110 | .dwp-key-details-bar .dwp-key-details-bar__key-details .dwp-key-details-bar__status { 111 | font-size: 14px; 112 | float: left; 113 | clear: both; 114 | margin-top: 5px; 115 | } 116 | } -------------------------------------------------------------------------------- /app/views/components/key-details-bar/examples/default/template.html: -------------------------------------------------------------------------------- 1 | {% from "key-details-bar/macro.njk" import dwpKeyDetailsBar %} 2 | 3 | {{ dwpKeyDetailsBar({ 4 | primaryIdentifier: { 5 | text: 'Name:', 6 | value: 'Jane Doe' 7 | }, 8 | secondaryIdentifier: { 9 | text: 'Nino:', 10 | value: 'QQ 12 34 56 X' 11 | }, 12 | status: { 13 | text: 'Claim status:', 14 | value: 'completed' 15 | }, 16 | additionalData: [ 17 | { 18 | value: "4 June 1972", 19 | text: "Date of birth:" 20 | }, 21 | { 22 | value: "07777 900 900", 23 | text: "Mobile number:" 24 | }, 25 | { 26 | value: "Welsh speaker", 27 | text: "Language:" 28 | } 29 | ] 30 | }) }} 31 | -------------------------------------------------------------------------------- /app/views/components/key-details-bar/examples/notdo/index.html: -------------------------------------------------------------------------------- 1 | {% extends "code.html" %} 2 | 3 | {% set pageTitle = "Key details bar" %} 4 | 5 | {% block pageContent %} 6 | {% include './template.html' %} 7 | {% endblock %} -------------------------------------------------------------------------------- /app/views/components/key-details-bar/examples/notdo/template.html: -------------------------------------------------------------------------------- 1 |
2 | 39 |
40 | -------------------------------------------------------------------------------- /app/views/components/key-details-bar/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "components" %} 4 | {% set pageTitle = "Key details bar" %} 5 | {% set pageId = "key-details-bar" %} 6 | 7 | {% block pageContent %} 8 |

Components {{pageTitle}}

9 | 10 | {% markdown %}{% include "./README.md.njk" %}{% endmarkdown %} 11 | 12 |
13 | {% include "_contact-panel.njk" %} 14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /app/views/components/timeline/README.md.njk: -------------------------------------------------------------------------------- 1 | Use the timeline component to show a linear record of what has happened. 2 | 3 | The timeline component has only been researched on agent-facing services. 4 | 5 | {{dsExample({ 6 | name: 'timeline', 7 | description: 'Appointments timeline', 8 | example: 'default', 9 | height: 454 10 | })}} 11 | 12 | ## When to use this component 13 | 14 | Use the timeline component when you need to show a history of information or events that can be followed in chronological order. 15 | 16 | The timeline should show a brief overview of what has happened at each point and should not be used to give in-depth information. 17 | 18 | ## When not to use this component 19 | 20 | The timeline should not be used to include and show large amounts of information. 21 | 22 | You should not use the timeline component if you need to let users know where they are in a journey. 23 | 24 | ## How it works 25 | 26 | The timeline should display information in chronological order, with the newest item appearing at the top of the timeline. 27 | 28 | Each entry in the timeline should include: 29 | 30 | 35 | 36 | 37 | ## Research on this component 38 | 39 | This component has been used on services across DWP, including: 40 | 41 | 48 | 49 | The timeline has only been researched on agent-facing services. More research is needed on the component. 50 | 51 | You can help to improve this pattern by: 52 | 53 | 59 | -------------------------------------------------------------------------------- /app/views/components/timeline/examples/default/index.html: -------------------------------------------------------------------------------- 1 | {% extends "code.html" %} 2 | 3 | {% set pageTitle = "Timeline" %} 4 | 5 | {% block pageContent %} 6 | {% include './template.html' %} 7 | {% endblock %} -------------------------------------------------------------------------------- /app/views/components/timeline/examples/default/styles.css: -------------------------------------------------------------------------------- 1 | .dwp-timeline { 2 | font-family: Arial, sans-serif; 3 | border-left: 3px solid #1d70b8; 4 | list-style-type: none; 5 | padding: 0; 6 | } 7 | 8 | .dwp-timeline__entry { 9 | margin: 2em 0; 10 | padding-left: 1.125em; 11 | position: relative; 12 | top: -.6em; 13 | } 14 | 15 | .dwp-timeline__entry::before { 16 | background-color: #1d70b8; 17 | content: ''; 18 | height: 3px; 19 | left: 0; 20 | position: absolute; 21 | top: .6em; 22 | width: 10px; 23 | } -------------------------------------------------------------------------------- /app/views/components/timeline/examples/default/template.html: -------------------------------------------------------------------------------- 1 | {% from "timeline/macro.njk" import dwpTimeline %} 2 | 3 | {{ dwpTimeline({ 4 | title: "Appointments", 5 | events: [ 6 | { 7 | name: "John Smith", 8 | state: "Accepted", 9 | date: "11 Aug 2021" 10 | }, 11 | { 12 | name: "John Smith", 13 | state: "Declined", 14 | date: "10 Aug 2021" 15 | } 16 | ] 17 | }) }} 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/views/components/timeline/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "components" %} 4 | {% set pageTitle = "Timeline" %} 5 | {% set pageId = "timeline" %} 6 | 7 | {% block pageContent %} 8 |

Components {{pageTitle}}

9 | 10 | {% markdown %}{% include "./README.md.njk" %}{% endmarkdown %} 11 | 12 |
13 | {% include "_contact-panel.njk" %} 14 |
15 | {% endblock %} -------------------------------------------------------------------------------- /app/views/get-started/README.md: -------------------------------------------------------------------------------- 1 | # Get started 2 | The DWP Design System is made up of commonly used patterns and components that are ready for use in live services and prototypes. 3 | 4 | This guidance assumes that you have already installed the [GOV.UK Prototype Kit](https://govuk-prototype-kit.herokuapp.com/docs). If you haven't, do that first. 5 | 6 | There are two ways to use the design system in your project. 7 | 8 | ## HTML and CSS 9 | You can use design system components in your prototype with minimal coding by copying and pasting from the code examples. Every code example includes production-ready HTML, and CSS if needed. 10 | 11 | Read a step by step guide at [Get started: HTML and CSS](get-started/html-and-css) 12 | 13 | ## Install using npm 14 | If you expect to use more than one or two components – or if you are setting up a new project – we recommend installing DWP Frontend using Node Package Manager (npm). 15 | 16 | This is a bit more technical than copying HTML and CSS and involves using Terminal commands, but it will be easier to maintain and update your code. 17 | 18 | Read a step by step guide at [Get started: install using npm](get-started/npm) -------------------------------------------------------------------------------- /app/views/get-started/html-and-css/README.md: -------------------------------------------------------------------------------- 1 | # Get started: HTML and CSS 2 | If your prototype uses the [GOV.UK Prototype Kit](https://govuk-prototype-kit.herokuapp.com/docs) you can use DWP components by copying the HTML from the code examples provided. 3 | 4 | If a code example doesn't include a CSS tab, it's because the pattern or component only uses styles already included in the GOV.UK Prototype Kit. You can just copy the HTML in these cases. 5 | 6 | If you don’t feel comfortable configuring your prototype or don’t have permission to do so, the person on your team who manages it should be able to make these changes for you. 7 | 8 | ## Step by step 9 | If the code sample includes CSS, you will need both the CSS and the HTML for it to work as intended. If it doesn't, you can just add the HTML to your pages. 10 | 11 | ### Add styles with CSS 12 | First, use CSS to add any new styles to your prototype: 13 | 14 | 1. In your code editor, go to your prototype’s folder and open the file `app > assets > sass > application.scss` 15 | 2. In the component’s code example select the ‘CSS’ tab and use the ‘Copy code’ button to copy to your clipboard 16 | 3. In `application.scss`, find the section marked ‘Add extra styles here’ 17 | 4. Paste the CSS code below this heading and save your changes 18 | 19 | ### Add the component with HTML 20 | You can now use HTML to add the component to individual pages: 21 | 22 | 5. In your code editor, open the page where you want to use the component 23 | 6. In the component’s code example select the ‘HTML’ tab and use the ‘Copy code’ button to copy to your clipboard 24 | 7. In your page, find the place where you want the component to appear 25 | 8. Paste the HTML into your page and save your changes 26 | 27 | Repeat these steps for each component you want to use. 28 | 29 | For more help, [email the design system team](mailto:dwp-design-system@engineering.digital.dwp.gov.uk) or use the [#design-system Slack channel](https://dwpdigital.slack.com/archives/CJ11B0VFV). 30 | -------------------------------------------------------------------------------- /app/views/get-started/html-and-css/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "get-started" %} 4 | {% set pageTitle = "Get started: HTML and CSS" %} 5 | {% set pageId = "html-css" %} 6 | 7 | {% block pageContent %} 8 | {% markdown %}{% include "./README.md" %}{% endmarkdown %} 9 | {% include "_contact-panel.njk" %} 10 | {% endblock %} -------------------------------------------------------------------------------- /app/views/get-started/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "get-started" %} 4 | {% set pageTitle = "Get started" %} 5 | {% set pageId = "get-started" %} 6 | 7 | {% block pageContent %} 8 | {% markdown %}{% include "./README.md" %}{% endmarkdown %} 9 | {% include "_contact-panel.njk" %} 10 | {% endblock %} -------------------------------------------------------------------------------- /app/views/get-started/npm/README.md: -------------------------------------------------------------------------------- 1 | # Get started: install using npm 2 | If you expect to use more than one or two components, or if you are setting up a new project, we recommend installing DWP Frontend. You can then use Nunjucks to add components to your prototype. 3 | 4 | ## Install DWP Frontend 5 | These instructions assume you are using the [GOV.UK Prototype Kit](https://govuk-prototype-kit.herokuapp.com/docs). 6 | 7 | 1. Start Terminal and navigate to your prototype’s root folder, for example: `cd projects/my-new-project` 8 | 9 | 2. Run `npm i @dwp/dwp-frontend` 10 | 11 | ## Add components to your prototype 12 | With DWP Frontend installed you can use the Nunjucks code from any component to add that component to your prototype. 13 | 14 | For instance, the following code imports the [Timeline](/components/timeline) component and then adds a timeline to a page. This particular timeline is called "Appointments" and has one event. 15 | 16 | {% raw %} 17 | ``` 18 | {% from "timeline/macro.njk" import dwpTimeline %} 19 | 20 | {{ dwpTimeline({ 21 | title: "Appointments", 22 | events: [ 23 | { 24 | name: "John Smith", 25 | state: "Accepted", 26 | date: "11 Aug 2021" 27 | } 28 | ] 29 | }) }} 30 | ``` 31 | {% endraw %} 32 | 33 | For more help setting up or using DWP Frontend, [email the design system team](mailto:dwp-design-system@engineering.digital.dwp.gov.uk) or use the [#design-system Slack channel](https://dwpdigital.slack.com/archives/CJ11B0VFV). 34 | -------------------------------------------------------------------------------- /app/views/get-started/npm/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "get-started" %} 4 | {% set pageTitle = "Get started: install using npm" %} 5 | {% set pageId = "dwp-frontend" %} 6 | 7 | {% block pageContent %} 8 | {% markdown %}{% include "./README.md" %}{% endmarkdown %} 9 | {% include "_contact-panel.njk" %} 10 | {% endblock %} -------------------------------------------------------------------------------- /app/views/index.html: -------------------------------------------------------------------------------- 1 | {% extends "full-width.html" %} 2 | {% set pageTitle = "Home" %} 3 | 4 | {% block pageContent %} 5 | 6 |
7 |
8 |
9 |
10 |

Design your service using DWP components and patterns

11 |

Use this design system to make your service consistent with DWP services. Learn from the research and experience of other service teams and avoid repeating work that’s already been done.

12 |
13 |
14 |
15 |
16 | 17 |
18 |
19 |
20 |
21 |

Components

22 |

Components are reusable parts of the user interface that have been made to support a variety of applications.

23 |
24 |
25 | {% include "_component-index.njk" %} 26 | 27 |
28 | 29 |
30 |
31 |

Patterns

32 |

Patterns are best practice design solutions for specific user-focused tasks and page types.

33 |
34 |
35 | {% include "_pattern-index.njk" %} 36 | 37 |
38 | 39 |
40 |
41 |

Contribute

42 |

43 | The DWP Design System is maintained by the DWP Design System team. Anyone can contribute to it by proposing new components or patterns and sharing their research and findings.

44 |
45 |
46 | {% include "_contribute-index.njk" %} 47 | 48 |
49 | 50 |
51 |
52 | {% include "_contact-panel.njk" %} 53 |
54 |
55 | 56 |
57 |
58 | {% endblock %} 59 | -------------------------------------------------------------------------------- /app/views/patterns/README.md: -------------------------------------------------------------------------------- 1 | # Patterns 2 | 3 | Patterns are best practice design solutions for specific user-focused tasks and page types. 4 | 5 | Patterns often use one or more [components](../components) and explain how to adapt them to the context. 6 | 7 | These patterns should be used in addition to those in the GOV.UK Design System. We will share the design and research of these patterns with the GOV.UK Design System so they can be used more widely. 8 | 9 | -------------------------------------------------------------------------------- /app/views/patterns/add-another-thing/example/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "patterns" %} 4 | {% set pageTitle = "Add another thing: example" %} 5 | {% set pageId = "add-another-thing" %} 6 | 7 | {% block pageContent %} 8 | 9 |

{{pageTitle}}

10 | 11 | {% markdown %}{% include "./README.md.njk" %}{% endmarkdown %} 12 | 13 |
14 | {% include "_contact-panel.njk" %} 15 |
16 | 17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /app/views/patterns/add-another-thing/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "patterns" %} 4 | {% set pageTitle = "Add another thing" %} 5 | {% set pageId = "add-another-thing" %} 6 | 7 | {% block pageContent %} 8 | 9 |

Help users to {{pageTitle}}

10 | 11 |
12 | {% markdown %}{% include "./README.md.njk" %}{% endmarkdown %} 13 |
14 | 15 |
16 | {% include "_contact-panel.njk" %} 17 |
18 | 19 | {% endblock %} 20 | -------------------------------------------------------------------------------- /app/views/patterns/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "patterns" %} 4 | {% set pageTitle = "Patterns" %} 5 | {% set pageId = "patterns" %} 6 | 7 | {% block subNav %} 8 | {% endblock %} 9 | 10 | {% block pageContent %} 11 | {% markdown %}{% include "./README.md" %}{% endmarkdown %} 12 | {% include "_pattern-table.njk" %} 13 | {% endblock %} 14 | 15 | {% block pageContentFoot %} 16 |

See all the patterns in the backlog

17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /app/views/patterns/make-a-declaration/README.md.njk: -------------------------------------------------------------------------------- 1 | Help users to tell you that they have understood or agree to something before they submit an application or an online form. This is known as a ‘declaration’. 2 | 3 | {{dsExample({ 4 | section: 'patterns', 5 | name: 'make-a-declaration', 6 | description: 'Declaration pattern', 7 | example: 'default', 8 | height: 454 9 | })}} 10 | 11 | ## When to use this pattern 12 | 13 | You should use the declaration pattern when you need a user to confirm that they have understood the information they have been given or you need them to agree to something. 14 | 15 | You should use this pattern if there are significant consequences to the user if they provide false information when using your service. 16 | 17 | It should also be used if using your service could alter the user's quality of life. For example, if applying for a benefit might reduce other support they may be receiving. 18 | 19 | 20 | ## When not to use this pattern 21 | 22 | Do not use this pattern to give users complex or complicated information about policy or legislation. 23 | 24 | ## How it works 25 | 26 | The content should be clear and concise. The declaration should be tailored to the service and include information about what will happen if the user makes a false declaration. 27 | 28 | 29 | ## Research on this pattern 30 | This pattern has been used in a number of DWP services. 31 | 32 | The pattern has been amended by some services to: 33 | 34 | 39 | 40 | Examples of these can be seen on the Apply for New Style Jobseeker’s Allowance and Apply for Pension Credit services. 41 | 42 | More research is needed on the pattern to validate the need for any changes to the pattern. 43 | 44 | You can help to improve this pattern by: 45 | 46 | 52 | -------------------------------------------------------------------------------- /app/views/patterns/make-a-declaration/examples/default/index.html: -------------------------------------------------------------------------------- 1 | {% extends "code.html" %} 2 | 3 | {% set pageTitle = "Make a declaration" %} 4 | 5 | {% block pageContent %} 6 | {% include './template.html' %} 7 | {% endblock %} -------------------------------------------------------------------------------- /app/views/patterns/make-a-declaration/examples/default/template.html: -------------------------------------------------------------------------------- 1 | {% from "button/macro.njk" import govukButton %} 2 | 3 |
4 |

Declaration

5 |

6 | By sending the application you agree that the information you have given is complete and correct. 7 | If you deliberately give the wrong or incomplete information, or you do not report any changes, you may: 8 |

9 | 14 | {{ govukButton({ 15 | text: "I agree – send my application" 16 | }) }} 17 |
18 | 19 | -------------------------------------------------------------------------------- /app/views/patterns/make-a-declaration/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "patterns" %} 4 | {% set pageTitle = "Make a declaration" %} 5 | {% set pageId = "make-a-declaration" %} 6 | 7 | {% block pageContent %} 8 | 9 |

Help users to {{pageTitle}}

10 | 11 | {% markdown %}{% include "./README.md.njk" %}{% endmarkdown %} 12 | 13 |
14 | {% include "_contact-panel.njk" %} 15 |
16 | 17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /app/views/patterns/manage-a-session-timeout/README.md.njk: -------------------------------------------------------------------------------- 1 | This is currently experimental because more research is needed. 2 | 3 | Use this pattern to warn users that their session is about to end and explain what has happened after the session has timed out. 4 | 5 | A timeout warning helps services meet WCAG 2.1 success criterion 2.2.1 'Timing Adjustable'. This means a service must warn users before a session timeout occurs and allow them to extend the session. 6 | 7 | Open the manage a session timeout example in a new window. 8 | 9 | ## When to use this pattern 10 | 11 | If your service has sessions, it will time the user out when they do not do anything for a set amount of time. This is for security reasons. 12 | 13 | You should warn a user at least 2 minutes before the end of this time. This will give them time to decide if they want to keep using the service. 14 | 15 | ## How it works 16 | 17 | Show the user the timeout warning at least 2 minutes before the time runs out. This should be shown to the user in a modal dialog, also known as a pop-up. The modal dialog is based on the information in the GOV.UK Design System community backlog. 18 | 19 | The user can: 20 | 21 | - select a button to stay in the service and not time out 22 | - press the escape key to close the warning, stay in the service and not time out 23 | - do nothing 24 | 25 | If the user does nothing within the time limit, redirect them to a timeout page. This page explains what has happened and gives them options for how to continue. 26 | 27 | ### When the user is signed in to a service 28 | 29 | If a user signs in to your service, tell them they will be signed out if the time runs out. You should tell the user if any information they have entered will be deleted or not. You should include a countdown of the remaining time. 30 | 31 | Open the signed in to a service example in a new window. 32 | 33 | If the user does not continue the session they are redirected to a page that tells them the time has run out. You should tell the user if any information they have entered has been deleted or not. 34 | 35 | {{dsExample({ 36 | section: 'patterns', 37 | name: 'manage-a-session-timeout', 38 | description: 'session timeout pattern with a user signed in', 39 | example: 'timedout-signedin', 40 | height: 300 41 | })}} 42 | 43 | ### When the user is not signed in to a service 44 | 45 | If a user is not signed in to your service, tell them their answers will be deleted if the time runs out. You should include a countdown of the remaining time. 46 | 47 | Open the not signed in to a service example in a new window. 48 | 49 | If the user does not continue the session they are redirected to a page that tells them the the time has run out. 50 | 51 | {{dsExample({ 52 | section: 'patterns', 53 | name: 'manage-a-session-timeout', 54 | description: 'session timeout pattern with a user signed out', 55 | example: 'timedout-notsignedin', 56 | height: 300 57 | })}} 58 | 59 | 60 | ## If the user’s device is not running JavaScript 61 | 62 | If the user’s device is not running JavaScript, display a banner which warns them about the timeout. The banner should include the content specified above for if a user is signed in or not signed into a service. 63 | 64 | {{dsExample({ 65 | section: 'patterns', 66 | name: 'manage-a-session-timeout', 67 | description: 'session timeout pattern with not running JavaScript', 68 | example: 'timedout-nojs', 69 | height: 300 70 | })}} 71 | 72 | ## Technical details 73 | 74 | The service team should work with security teams to agree the length of inactivity before the user is timed out of a session. The modal dialogue example is based on code from the GOV.UK Design System community backlog. We recommend at least 20 minutes. Services should not limit the number of times users can extend their session. 75 | 76 | ## Research on this pattern 77 | 78 | More research is needed on the pattern. If you have used the session timeout pattern, get in touch to share your research findings. 79 | 80 | You can help to improve this pattern by: 81 | 82 | 88 | -------------------------------------------------------------------------------- /app/views/patterns/manage-a-session-timeout/examples/default/index.html: -------------------------------------------------------------------------------- 1 | {% extends "code.html" %} 2 | 3 | {% set pageTitle = "Manage session timeout" %} 4 | 5 | {% block pageContent %} 6 | {% include './template.html' %} 7 | {% endblock %} -------------------------------------------------------------------------------- /app/views/patterns/manage-a-session-timeout/examples/default/template.html: -------------------------------------------------------------------------------- 1 | 12 |

13 | Your application will be closed soon 14 |

15 |
16 | 17 |
22 |
23 | 29 |
30 | 31 | -------------------------------------------------------------------------------- /app/views/patterns/manage-a-session-timeout/examples/notsignedin/index.html: -------------------------------------------------------------------------------- 1 | {% extends "code.html" %} 2 | 3 | {% set pageTitle = "Manage session timeout" %} 4 | 5 | {% block pageContent %} 6 | {% include './template.html' %} 7 | {% endblock %} -------------------------------------------------------------------------------- /app/views/patterns/manage-a-session-timeout/examples/notsignedin/template.html: -------------------------------------------------------------------------------- 1 | 12 |

13 | Your answers will be deleted soon 14 |

15 |
16 |

We will delete your answers if you do not continue in the next 2 minutes. This is to protect your information.

17 |
18 | 19 |
-------------------------------------------------------------------------------- /app/views/patterns/manage-a-session-timeout/examples/signedin/index.html: -------------------------------------------------------------------------------- 1 | {% extends "code.html" %} 2 | 3 | {% set pageTitle = "Manage session timeout" %} 4 | 5 | {% block pageContent %} 6 | {% include './template.html' %} 7 | {% endblock %} -------------------------------------------------------------------------------- /app/views/patterns/manage-a-session-timeout/examples/signedin/template.html: -------------------------------------------------------------------------------- 1 | 12 |

13 | You will be signed out soon 14 |

15 |
16 |

For your security, you will be signed out in 2 minutes.

17 |
18 | 19 |
-------------------------------------------------------------------------------- /app/views/patterns/manage-a-session-timeout/examples/timedout-nojs/index.html: -------------------------------------------------------------------------------- 1 | {% extends "code.html" %} 2 | 3 | {% set pageTitle = "Manage session timeout" %} 4 | 5 | {% block pageContent %} 6 | {% include './template.html' %} 7 | {% endblock %} -------------------------------------------------------------------------------- /app/views/patterns/manage-a-session-timeout/examples/timedout-nojs/template.html: -------------------------------------------------------------------------------- 1 | {% from "notification-banner/macro.njk" import govukNotificationBanner %} 2 | 3 | {% set html %} 4 |
5 |

We will delete your answers if you do not do anything for 20 minutes and you will have to start again. This is to protect your information.

6 |
7 | 8 | {% endset %} 9 | 10 | {{ govukNotificationBanner({ 11 | html: html, 12 | classes: "govuk-notification-banner--blue" 13 | }) }} 14 | 15 | -------------------------------------------------------------------------------- /app/views/patterns/manage-a-session-timeout/examples/timedout-notsignedin/index.html: -------------------------------------------------------------------------------- 1 | {% extends "code.html" %} 2 | 3 | {% set pageTitle = "Manage session timeout" %} 4 | 5 | {% block pageContent %} 6 | {% include './template.html' %} 7 | {% endblock %} -------------------------------------------------------------------------------- /app/views/patterns/manage-a-session-timeout/examples/timedout-notsignedin/template.html: -------------------------------------------------------------------------------- 1 |

2 | Your answers have been deleted 3 |

4 |
5 |

We have deleted your answers because you did not do anything for 20 minutes. This is to protect your information.

6 |

You will need to start again.

7 |
8 | 9 | -------------------------------------------------------------------------------- /app/views/patterns/manage-a-session-timeout/examples/timedout-signedin/index.html: -------------------------------------------------------------------------------- 1 | {% extends "code.html" %} 2 | 3 | {% set pageTitle = "Manage session timeout" %} 4 | 5 | {% block pageContent %} 6 | {% include './template.html' %} 7 | {% endblock %} -------------------------------------------------------------------------------- /app/views/patterns/manage-a-session-timeout/examples/timedout-signedin/template.html: -------------------------------------------------------------------------------- 1 |

2 | You have been signed out 3 |

4 |
5 |

You have been signed out and any information you have not saved has been deleted because you did not do anything for 20 minutes. This is to protect your information.

6 |
7 | 8 | -------------------------------------------------------------------------------- /app/views/patterns/manage-a-session-timeout/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "patterns" %} 4 | {% set pageTitle = "Manage a session timeout" %} 5 | {% set pageId = "manage-a-session-timeout" %} 6 | 7 | {% block pageContent %} 8 | 9 |

Help users to {{pageTitle}}

10 | 11 | {% markdown %}{% include "./README.md.njk" %}{% endmarkdown %} 12 | 13 |
14 | {% include "_contact-panel.njk" %} 15 |
16 | 17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /app/views/patterns/manage-a-session-timeout/macro.njk: -------------------------------------------------------------------------------- 1 | {% macro dsTimeoutWarning(params) %} 2 | {%- include "./template.njk" -%} 3 | {% endmacro %} 4 | -------------------------------------------------------------------------------- /app/views/patterns/manage-a-session-timeout/template.html: -------------------------------------------------------------------------------- 1 | {% from "govukNotificationBanner/macro.njk" import govukNotificationBanner %} 2 | 3 | {% set html %} 4 |
5 |

6 | Your answers will be deleted soon 7 |

8 |
9 |

We will delete your answers if you do not continue in the next 2 minutes. This is to protect your information.

10 |
11 | 12 |
13 | {% endset %} 14 | 15 | {{ govukNotificationBanner({ 16 | html: html 17 | }) }} 18 | 19 | 27 |

28 | Your application will be closed soon 29 |

30 |
31 | 32 |
33 |
34 | 35 |
36 | -------------------------------------------------------------------------------- /app/views/patterns/manage-a-session-timeout/timed-out.html: -------------------------------------------------------------------------------- 1 | {% extends "basic.html" %} 2 | 3 | 4 | {% block pageTitle %} 5 | You’ll have to start again 6 | {% endblock %} 7 | 8 | {% block pageContent %} 9 | 10 |
11 |
12 | 13 |

14 | Your application has timed out 15 |

16 | 17 |

We have reset your application because you did not do anything for 30 minutes. We did this to keep your information secure.

18 | 19 |

20 | Start application again 21 |

22 |

If you don’t want to start again, you can return to GOV.UK.

23 | 24 |
25 |
26 | 27 | {% endblock %} 28 | -------------------------------------------------------------------------------- /app/views/patterns/retired-patterns/README.md.njk: -------------------------------------------------------------------------------- 1 | # Retired patterns 2 | 3 | Patterns and components are retired when they are no longer needed: usually when there is a pattern in the GOV.UK Design System that meets the same need. 4 | 5 | -------------------------------------------------------------------------------- /app/views/patterns/retired-patterns/consent-to-cookies/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "patterns" %} 4 | {% set pageTitle = "Consent to cookies" %} 5 | {% set pageId = "retired-patterns" %} 6 | 7 | {% block pageContent %} 8 | 9 |

Help users to {{pageTitle}}

10 | 11 | {{ govukTag({ 12 | classes: 'govuk-!-margin-bottom-2 dwp-\!-background-dark-grey', 13 | text: 'Retired' 14 | }) }} 15 | 16 | {% markdown %}{% include "./README.md.njk" %}{% endmarkdown %} 17 | 18 |
19 | {% include "_contact-panel.njk" %} 20 |
21 | 22 | {% endblock %} 23 | -------------------------------------------------------------------------------- /app/views/patterns/retired-patterns/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "patterns" %} 4 | {% set pageTitle = "Retired patterns" %} 5 | {% set pageId = "retired-patterns" %} 6 | 7 | {% block pageContent %} 8 | {% markdown %}{% include "./README.md.njk" %}{% endmarkdown %} 9 | {% include "_contact-panel.njk" %} 10 | {% endblock %} -------------------------------------------------------------------------------- /app/views/patterns/toggle-to-welsh/README.md.njk: -------------------------------------------------------------------------------- 1 | This pattern lets the user change the language used in a service from English to Welsh and from Welsh to English. 2 | 3 | ## When to use this pattern 4 | 5 | Use the Welsh language toggle when a service is available in Welsh. 6 | 7 | ## When not to use this pattern 8 | 9 | Do not use the Welsh language toggle when a service has no Welsh language option. 10 | 11 | ## How it works 12 | 13 | You should put the toggle to Welsh on the right-hand side below the: 14 | 15 | 19 | 20 | The Welsh language toggle should appear on every page of the service. 21 | 22 | When a user selects a language the page should change to the language selected. The user should be shown this language for the rest of the journey unless they decide to change to the other language option. 23 | 24 | When a user selects a language they should stay on the same page of the service. They should not be taken back to the beginning of the service. Any information they have already entered should be kept. 25 | 26 | {{dsExample({ 27 | section: 'patterns', 28 | name: 'toggle-to-welsh', 29 | description: 'welsh toggle pattern', 30 | example: 'default', 31 | height: 300 32 | })}} 33 | 34 | ### If your service is not able to use the toggle to Welsh pattern 35 | 36 | If you're unable to use the toggle to Welsh pattern on your service you should include a signpost to the Welsh language option on the start page of the service. 37 | 38 | Do not place the Welsh language option in the footer of the page. 39 | 40 | {{dsExample({ 41 | section: 'patterns', 42 | name: 'toggle-to-welsh', 43 | description: 'welsh language option pattern', 44 | example: 'start-page', 45 | height: 350 46 | })}} 47 | 48 | ## Accessibility requirements 49 | 50 | To meet WCAG 2.1 success criteria [3.1.1 Language of page](https://www.w3.org/WAI/WCAG21/Understanding/language-of-page) and [3.1.2 Language of parts](https://www.w3.org/WAI/WCAG21/Understanding/language-of-parts) services should make sure the language attribute has been applied properly. This helps things like screen readers to pronounce the content correctly. 51 | 52 | In the English version of the service: 53 | - the page's default language must be set to English with `` 54 | - the link text 'Cymraeg' must be set to Welsh with `lang=cy` 55 | 56 | In the Welsh version of the service: 57 | - the page's default language must be set to Welsh with `` 58 | - the link text 'English' must be set to English with `lang=en` 59 | 60 | The inactive toggle text ('English' on the English version of the site, 'Cymraeg' on the Welsh version) does not need a separate language attribute because it is in the default language of the page. 61 | 62 | ## Research on this pattern 63 | 64 | More research is needed on this pattern. 65 | 66 | You can help to improve this pattern by: 67 | 68 | 74 | -------------------------------------------------------------------------------- /app/views/patterns/toggle-to-welsh/examples/default/index.html: -------------------------------------------------------------------------------- 1 | {% extends "code.html" %} 2 | 3 | {% set pageTitle = "Toggle welsh" %} 4 | 5 | {% block pageContent %} 6 | {% include './template.html' %} 7 | {% endblock %} -------------------------------------------------------------------------------- /app/views/patterns/toggle-to-welsh/examples/default/template.html: -------------------------------------------------------------------------------- 1 | {% from "internal-services-header/macro.njk" import dwpHeader %} 2 | 3 | {{ dwpHeader({ 4 | name: "Apply for a benefit" 5 | }) }} 6 | 7 |
8 |

9 | 12 | 13 | This is a new service – your feedback (opens in a new window) will help us to improve it. 14 | 15 |

16 |
17 | 28 | -------------------------------------------------------------------------------- /app/views/patterns/toggle-to-welsh/examples/start-page/index.html: -------------------------------------------------------------------------------- 1 | {% extends "code.html" %} 2 | 3 | {% set pageTitle = "Make a declaration" %} 4 | 5 | {% block pageContent %} 6 | {% include './template.html' %} 7 | {% endblock %} -------------------------------------------------------------------------------- /app/views/patterns/toggle-to-welsh/examples/start-page/template.html: -------------------------------------------------------------------------------- 1 | {% from "button/macro.njk" import govukButton %} 2 | 3 |
4 | 5 |
6 |
7 |
8 |

Apply for a benefit

9 | 10 |

Find out if you can apply for a benefit

11 | 12 |

This service is also available in Welsh (Cymraeg).

13 | 14 | 15 | Start 16 | 19 | 20 |
21 |
22 |
23 |
24 | -------------------------------------------------------------------------------- /app/views/patterns/toggle-to-welsh/index.html: -------------------------------------------------------------------------------- 1 | {% extends "sidebar-width.html" %} 2 | 3 | {% set sectionId = "patterns" %} 4 | {% set pageTitle = "Toggle to Welsh" %} 5 | {% set pageId = "toggle-to-welsh" %} 6 | 7 | {% block pageContent %} 8 | 9 |

Help users to {{pageTitle}}

10 | 11 | {% markdown %}{% include "./README.md.njk" %}{% endmarkdown %} 12 | 13 |
14 | {% include "_contact-panel.njk" %} 15 |
16 | 17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /config/content/backlog-page.json: -------------------------------------------------------------------------------- 1 | { 2 | "backlogSections": [ 3 | { 4 | "title": "In progress", 5 | "items": [ 6 | { 7 | "name": "Get help with an application or service", 8 | "url": "https://github.com/dwp/design-system/issues/238" 9 | } 10 | ] 11 | }, 12 | { 13 | "title": "To do", 14 | "items": [ 15 | { 16 | "name": "Filters", 17 | "url": "https://github.com/dwp/design-system-community-backlog/issues/28" 18 | }, 19 | { 20 | "name": "Contact preferences", 21 | "url": "https://github.com/dwp/design-system-community-backlog/issues/51" 22 | }, 23 | { 24 | "name": "Navigation menu", 25 | "url": "https://github.com/dwp/design-system-community-backlog/issues/25" 26 | } 27 | ] 28 | }, 29 | { 30 | "title": "Proposed", 31 | "items": [ 32 | { 33 | "name": "Advisor instructions/actions", 34 | "url": "https://github.com/dwp/design-system-community-backlog/issues/30" 35 | }, 36 | { 37 | "name": "Claim start date", 38 | "url": "https://github.com/dwp/design-system-community-backlog/issues/57" 39 | }, 40 | { 41 | "name": "Confirm action", 42 | "url": "https://github.com/dwp/design-system-community-backlog/issues/29" 43 | }, 44 | { 45 | "name": "Confirmation of actions of agent screens", 46 | "url": "https://github.com/dwp/design-system-community-backlog/issues/61" 47 | }, 48 | { 49 | "name": "Display CIS markers", 50 | "url": "https://github.com/dwp/design-system-community-backlog/issues/56" 51 | }, 52 | { 53 | "name": "Error/Timeout pages when we cannot infer the language", 54 | "url": "https://github.com/dwp/design-system-community-backlog/issues/65" 55 | }, 56 | { 57 | "name": "Find my address by postcode/house number", 58 | "url": "https://github.com/dwp/design-system-community-backlog/issues/8" 59 | }, 60 | { 61 | "name": "Find someone", 62 | "url": "https://github.com/dwp/design-system-community-backlog/issues/31" 63 | }, 64 | { 65 | "name": "Pagination control", 66 | "url": "https://github.com/dwp/design-system-community-backlog/issues/53" 67 | }, 68 | { 69 | "name": "Presenting the amount and terms of financial support", 70 | "url": "https://github.com/dwp/design-system-community-backlog/issues/32" 71 | }, 72 | { 73 | "name": "Search", 74 | "url": "https://github.com/dwp/design-system-community-backlog/issues/27" 75 | }, 76 | { 77 | "name": "Staying safe online", 78 | "url": "https://github.com/dwp/design-system-community-backlog/issues/5" 79 | }, 80 | { 81 | "name": "Upload documents", 82 | "url": "https://github.com/dwp/design-system-community-backlog/issues/62" 83 | } 84 | ] 85 | }, 86 | { 87 | "title": "DWP Design Examples", 88 | "items": [ 89 | { 90 | "name": "Accessible date picker", 91 | "url": "https://dwpdigital.atlassian.net/wiki/spaces/INTD/pages/132216489830/Accessible+date+picker" 92 | }, 93 | { 94 | "name": "Agent interfaces", 95 | "url": "https://dwpdigital.atlassian.net/wiki/spaces/INTD/pages/132204463135/Agent+interfaces" 96 | }, 97 | { 98 | "name": "Alternative formats", 99 | "url": "https://dwpdigital.atlassian.net/wiki/spaces/INTD/pages/132256924926/Alternative+Formats" 100 | }, 101 | { 102 | "name": "Asking for binary sex data", 103 | "url": "https://dwpdigital.atlassian.net/wiki/spaces/INTD/pages/131986494178/Asking+for+binary+sex+data" 104 | }, 105 | { 106 | "name": "Capture International Addresses", 107 | "url": "https://dwpdigital.atlassian.net/wiki/spaces/INTD/pages/132208788778/Capture" 108 | }, 109 | { 110 | "name": "Citizen facing Habitual Residency test [Residency]", 111 | "url": "https://dwpdigital.atlassian.net/wiki/spaces/INTD/pages/131987087895/Citizen+facing+Habitual+Residency+test+Residency" 112 | }, 113 | { 114 | "name": "Find a citizen record (National Insurance number)", 115 | "url": "https://dwpdigital.atlassian.net/wiki/spaces/INTD/pages/132105734313/Find+a+citizen+record+National+Insurance+number" 116 | }, 117 | { 118 | "name": "Get support to use the digital service", 119 | "url": "https://dwpdigital.atlassian.net/wiki/spaces/INTD/pages/132095413448/Get+support+to+use+the+digital+service" 120 | }, 121 | { 122 | "name": "Print something", 123 | "url": "https://dwpdigital.atlassian.net/wiki/spaces/INTD/pages/131986494319/Print+something" 124 | }, 125 | { 126 | "name": "Sign out of a service", 127 | "url": "https://dwpdigital.atlassian.net/wiki/spaces/INTD/pages/132240245154/Sign+out+of+a+service" 128 | } 129 | ] 130 | } 131 | ] 132 | } -------------------------------------------------------------------------------- /gulp/clean.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp'); 2 | const clean = require('gulp-clean'); 3 | 4 | gulp.task('clean', () => gulp.src('public', { read: false, allowEmpty: true }) 5 | .pipe(clean())); 6 | -------------------------------------------------------------------------------- /gulp/compile-app-js.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp'); 2 | const webpack = require('webpack-stream'); 3 | const rename = require('gulp-rename'); 4 | 5 | gulp.task('compile-app-js', () => gulp.src([ 6 | 'app/assets/javascript/**/*.js', 7 | ]) 8 | .pipe(webpack( 9 | { 10 | mode: 'production', 11 | stats: 'errors-only', 12 | }, 13 | )) 14 | .pipe(rename('application.min.js')) 15 | .pipe(gulp.dest('public/javascript/'))); 16 | -------------------------------------------------------------------------------- /gulp/copy-assets.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp'); 2 | 3 | gulp.task('copy-assets', () => gulp.src([ 4 | '!app/assets/sass{,/**/*}', 5 | 'app/assets/images{,/**/*}', 6 | 'app/assets/videos{,/**/*}', 7 | ]) 8 | .pipe(gulp.dest('public/'))); 9 | -------------------------------------------------------------------------------- /gulp/sass.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp'); 2 | const sass = require('gulp-sass')(require('node-sass')); 3 | 4 | gulp.task('sass', () => gulp.src('app/assets/sass/*.scss') 5 | .pipe(sass({ 6 | outputStyle: 'expanded', 7 | }).on('error', sass.logError)) 8 | .pipe(gulp.dest('public/stylesheets'))); 9 | -------------------------------------------------------------------------------- /gulp/server.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp'); 2 | const nodemon = require('gulp-nodemon'); 3 | 4 | gulp.task('server', (done) => { 5 | nodemon({ 6 | script: 'server.js', 7 | ext: 'js json', 8 | }).on('quit', () => { 9 | process.exit(0); 10 | }, done()); 11 | }); 12 | -------------------------------------------------------------------------------- /gulp/watch.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp'); 2 | 3 | gulp.task('watch-sass', (done) => gulp.watch([ 4 | 'app/assets/sass/**/*.scss', 5 | 'app/components/**/*.scss', 6 | ], gulp.task('sass'), done())); 7 | 8 | gulp.task('watch-assets', (done) => gulp.watch([ 9 | 'app/assets/images/**', 10 | 'app/assets/videos/**', 11 | 'app/components/**', 12 | 'app/assets/javascript/**'], 13 | { cwd: './' }, 14 | gulp.series('copy-assets', 'compile-app-js'), done())); 15 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp'); 2 | const requireDir = require('require-dir'); 3 | 4 | requireDir('./gulp', { recurse: true }); 5 | 6 | gulp.task('generate-assets', gulp.series( 7 | 'clean', 8 | gulp.parallel( 9 | 'copy-assets', 10 | 'compile-app-js', 11 | 'sass', 12 | ), 13 | )); 14 | 15 | gulp.task('watch', gulp.parallel( 16 | 'watch-sass', 17 | 'watch-assets', 18 | )); 19 | 20 | gulp.task('default', gulp.series( 21 | 'generate-assets', 22 | gulp.parallel( 23 | 'watch', 24 | 'server', 25 | ), 26 | )); 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dwp-design-system", 3 | "version": "2.0.0", 4 | "description": "DWP Design System", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "gulp", 8 | "lint": "eslint --ignore-path .gitignore .", 9 | "reports": "pa11y-ci" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/dwp/design-system.git" 14 | }, 15 | "author": "Adam Silver, Trevor Saint, Jon Hurrell, Simone Duca", 16 | "license": "MIT", 17 | "bugs": { 18 | "url": "https://github.com/dwp/design-system" 19 | }, 20 | "homepage": "https://github.com/dwp/design-system#readme", 21 | "engines": { 22 | "node": "12.13.1" 23 | }, 24 | "dependencies": { 25 | "@dwp/dwp-frontend": "2.2.1", 26 | "@dwp/eslint-config-base": "6.0.0", 27 | "cookie-parser": "1.4.6", 28 | "dialog-polyfill": "0.5.6", 29 | "express": "4.18.1", 30 | "govuk-frontend": "4.2.0", 31 | "gray-matter": "4.0.3", 32 | "gulp": "4.0.2", 33 | "gulp-clean": "0.4.0", 34 | "gulp-nodemon": "2.5.0", 35 | "gulp-rename": "2.0.0", 36 | "gulp-sass": "5.1.0", 37 | "highlight.js": "11.5.1", 38 | "js-beautify": "1.14.4", 39 | "js-yaml": "4.1.0", 40 | "markdown-it": "12.3.2", 41 | "marked": "3.0.4", 42 | "node-sass": "7.0.1", 43 | "nunjucks": "3.2.3", 44 | "nunjucks-highlight.js": "0.0.5", 45 | "nunjucks-markdown": "2.0.1", 46 | "pa11y-ci-reporter-html": "4.0.0", 47 | "require-dir": "1.2.0", 48 | "webpack-stream": "6.1.2" 49 | } 50 | } -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | // Core dependencies 2 | const path = require('path'); 3 | 4 | // NPM dependencies 5 | const express = require('express'); 6 | const nunjucks = require('nunjucks'); 7 | const markdown = require('nunjucks-markdown'); 8 | const marked = require('marked'); 9 | const cookieParser = require('cookie-parser'); 10 | const NunjucksCodeHighlight = require('nunjucks-highlight.js'); 11 | const hljs = require('highlight.js'); 12 | const fileHelper = require('./app/utils/file-helper'); 13 | 14 | const highlight = new NunjucksCodeHighlight(nunjucks, hljs); 15 | 16 | // Routing 17 | const routes = require('./app/routes/index'); 18 | const autoRoutes = require('./app/routes/auto'); 19 | 20 | // Middleware 21 | const { errorHandler } = require('./app/middleware/errorHandler'); 22 | const { urlPartials } = require('./app/middleware/urlPartials'); 23 | 24 | // Port 25 | const port = process.env.PORT || 3000; 26 | 27 | // Application 28 | const app = express(); 29 | 30 | // Setup application 31 | const appViews = [ 32 | path.join(__dirname, '/node_modules/@dwp/dwp-frontend/'), 33 | path.join(__dirname, '/node_modules/@dwp/dwp-frontend/components'), 34 | path.join(__dirname, '/node_modules/govuk-frontend/govuk/'), 35 | path.join(__dirname, '/node_modules/govuk-frontend/govuk/components'), 36 | path.join(__dirname, 'app/views'), 37 | path.join(__dirname, 'app/views/components'), 38 | path.join(__dirname, 'app/views/patterns'), 39 | path.join(__dirname, 'app/views/_layouts'), 40 | path.join(__dirname, 'app/views/_partials'), 41 | ]; 42 | 43 | // Configurations 44 | const nunjucksEnvironment = nunjucks.configure(appViews, { 45 | autoescape: true, 46 | express: app, 47 | noCache: true, 48 | watch: true, 49 | }); 50 | 51 | nunjucksEnvironment.addGlobal('getMacroParams', fileHelper.getMacroParams); 52 | nunjucksEnvironment.addGlobal('getNunjucksCode', fileHelper.getNunjucksCode); 53 | nunjucksEnvironment.addGlobal('getHtmlCode', fileHelper.getHtmlCode); 54 | nunjucksEnvironment.addGlobal('getCSSCode', fileHelper.getCSSCode); 55 | nunjucksEnvironment.addExtension('NunjucksCodeHighlight', highlight); 56 | 57 | // Set view engine 58 | app.set('view engine', 'html'); 59 | 60 | app.use(express.json()); 61 | app.use(express.urlencoded({ extended: false })); 62 | app.use(cookieParser()); 63 | 64 | // Middleware to serve static assets 65 | app.use('/public', express.static(path.join(__dirname, '/public'))); 66 | app.use('/assets', express.static(path.join(__dirname, 'node_modules', 'govuk-frontend', 'govuk', 'assets'))); 67 | 68 | app.use(urlPartials); 69 | 70 | // Use routes 71 | app.use(routes); 72 | app.use(autoRoutes); 73 | 74 | app.use(errorHandler); 75 | 76 | const renderer = new marked.Renderer(); 77 | 78 | marked.setOptions({ 79 | renderer, 80 | gfm: true, 81 | tables: true, 82 | breaks: true, 83 | pendantic: true, 84 | sanitize: false, 85 | smartLists: true, 86 | smartypants: true, 87 | }); 88 | 89 | // Markdown register 90 | markdown.register(nunjucksEnvironment, marked); 91 | 92 | // Start app 93 | app.listen(port, (err) => { 94 | if (err) { 95 | throw err; 96 | } else { 97 | console.log('Listening on port 3000 url: http://localhost:3000'); 98 | } 99 | }); 100 | 101 | module.exports = app; 102 | --------------------------------------------------------------------------------