Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
owenatgov committed Feb 24, 2025
1 parent 065e223 commit cd3b5af
Show file tree
Hide file tree
Showing 13 changed files with 185 additions and 7 deletions.
1 change: 1 addition & 0 deletions packages/govuk-frontend-review/src/app.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export default async () => {
app.use(middleware.request)
app.use(middleware.robots)
app.use(middleware.banner)
app.use(middleware.recolour)

// Add build stats
app.locals.stats = Object.fromEntries(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
export { default as assets } from './assets.mjs'
export { default as banner } from './banner.mjs'
export { default as docs } from './docs.mjs'
export { default as recolour } from './recolour.mjs'
export { default as request } from './request.mjs'
export { default as robots } from './robots.mjs'
45 changes: 45 additions & 0 deletions packages/govuk-frontend-review/src/common/middleware/recolour.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import express from 'express'

const router = express.Router()

const RECOLOUR_COOKIE_NAME = 'use-recolour'

router.use((req, res, next) => {
// If we have the expected query param in the URL handle the cookie setting
if (req.method === 'GET' && 'recolour' in req.query) {
if (req.query.recolour === 'true') {
const maxAgeInDays = 28

res.cookie(RECOLOUR_COOKIE_NAME, 'yes', {
maxAge: maxAgeInDays * 24 * 60 * 60 * 1000,
httpOnly: true
})
} else {
res.clearCookie(RECOLOUR_COOKIE_NAME)
}

const urlWithoutQueryString = req.url.split('?')[0]
return res.redirect(urlWithoutQueryString)

Check warning

Code scanning / CodeQL

Server-side URL redirect Medium

Untrusted URL redirection depends on a
user-provided value
.
}

// Let express carry on and handle the request as usual
next()
})

router.use((req, res, next) => {
if ('recolourOverride' in req.query) {
res.locals.useRecolourClass = req.query.recolourOverride !== 'false'
} else {
res.locals.useRecolourClass = req.cookies?.[RECOLOUR_COOKIE_NAME] === 'yes'
}

next()
})

router.use((req, res, next) => {
res.locals.showAllFlagStates =
'showAllFlagStates' in req.query && req.query.showAllFlagStates === 'true'
next()
})

export default router
1 change: 1 addition & 0 deletions packages/govuk-frontend-review/src/stylesheets/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ $govuk-suppressed-warnings: ("organisation-colours");
@import "partials/app";
@import "partials/code";
@import "partials/banner";
@import "partials/feature-flag-banner";
@import "partials/organisation-swatch";
@import "partials/prose";
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
@import "govuk/base";
@import "govuk/core";

.app-header--campaign {
.app-header--campaign,
.govuk-feature--recolour .app-header--campaign {
padding-bottom: govuk-spacing(2);
}

.govuk-feature--recolour .app-header--campaign {
padding-bottom: 0;
border-bottom: $govuk-border-width-wide solid #fff500;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.app-feature-flag-banner {
padding: govuk-spacing(4) 0;
border-bottom: 1px solid govuk-colour("mid-grey");
background-color: govuk-colour("light-grey");
}
7 changes: 6 additions & 1 deletion packages/govuk-frontend-review/src/views/component.njk
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{% from "govuk/components/breadcrumbs/macro.njk" import govukBreadcrumbs %}
{% from "macros/showExamples.njk" import showExamples %}
{% from "macros/featureFlags.njk" import featureFlags %}

{% extends "layouts/full-width-landmarks.njk" %}

Expand All @@ -11,6 +12,10 @@
{% include componentName + "/" + componentName + ".njk" ignore missing %}
{% endset %}

{% block featureFlags %}
{{ featureFlags(useRecolourClass, true, showAllFlagStates) }}
{% endblock %}

{% block beforeContent %}
{{ govukBreadcrumbs({
items: [
Expand Down Expand Up @@ -39,6 +44,6 @@
</div>

{% block examples %}
{{ showExamples(componentFixtures) }}
{{ showExamples(componentFixtures, false, showAllFlagStates) }}
{% endblock %}
{% endblock %}
5 changes: 5 additions & 0 deletions packages/govuk-frontend-review/src/views/layouts/_generic.njk
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{% extends "govuk/template.njk" %}

{% from "../macros/featureFlags.njk" import featureFlags %}

{% block head %}
<link rel="stylesheet" href="/stylesheets/app.min.css">

Expand All @@ -10,6 +12,9 @@
{% block banner %}
{% include "../partials/banner.njk" %}
{% endblock %}
{% block featureFlags %}
{{ featureFlags(useRecolourClass) }}
{% endblock %}
{% endblock %}

{% set mainClasses = 'govuk-main-wrapper--auto-spacing' %}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{% extends "layouts/_generic.njk" %}

{% set htmlClasses = "govuk-feature--recolour" if useRecolourClass else "" %}


{% block banner %}
{% include "../partials/exampleBanner.njk" %}
{% endblock %}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{% extends "layouts/_generic.njk" %}

{% set htmlClasses = "app-template" %}
{% set htmlClasses = "app-template" + " govuk-feature--recolour" if useRecolourClass else "" %}

{% block pageTitle %}GOV.UK Frontend{% endblock %}

Expand Down
15 changes: 15 additions & 0 deletions packages/govuk-frontend-review/src/views/macros/featureFlags.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{% macro featureFlags(useRecolourClass, showBothStatesButton, showBothStatesParam) %}
<div class="app-feature-flag-banner">
<div class="govuk-width-container">
<h2 class="govuk-heading-m">Feature flag control</h2>
<a class="govuk-button govuk-!-margin-bottom-0" href="?recolour={{ not useRecolourClass }}">
Turn {{ 'off' if useRecolourClass else 'on' }} updated header
</a>
{% if showBothStatesButton %}
<a class="govuk-button govuk-!-margin-bottom-0" href="?showAllFlagStates={{ not showBothStatesParam }}">
{{ 'Only show one state' if showBothStatesParam else 'Show both states' }}
</a>
{% endif %}
</div>
</div>
{% endmacro %}
18 changes: 14 additions & 4 deletions packages/govuk-frontend-review/src/views/macros/showExamples.njk
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{% from "govuk/components/details/macro.njk" import govukDetails %}

{% macro showExamples(componentFixtures, exampleNames) %}
{% macro showExamples(componentFixtures, exampleNames, renderTwoIframes) %}

{% set componentName = componentFixtures.component %}

Expand Down Expand Up @@ -32,9 +32,19 @@
</p>
{% endif %}
</div>
<div class="app-component-preview">
<iframe src="{{ path }}?iframe=true" loading="{{ "eager" if loop.index <= 3 else "lazy" }}" class="js-component-preview app-component-preview__iframe"></iframe>
</div>

{% if renderTwoIframes %}
<div class="app-component-preview">
<iframe src="{{ path }}?iframe=true&recolourOverride=true" loading="{{ "eager" if loop.index <= 3 else "lazy" }}" class="js-component-preview app-component-preview__iframe"></iframe>
</div>
<div class="app-component-preview">
<iframe src="{{ path }}?iframe=true&recolourOverride=false" loading="{{ "eager" if loop.index <= 3 else "lazy" }}" class="js-component-preview app-component-preview__iframe"></iframe>
</div>
{% else %}
<div class="app-component-preview">
<iframe src="{{ path }}?iframe=true" loading="{{ "eager" if loop.index <= 3 else "lazy" }}" class="js-component-preview app-component-preview__iframe"></iframe>
</div>
{% endif %}

<div class="govuk-width-container">
{% set codeExamplesHtml %}
Expand Down
82 changes: 82 additions & 0 deletions packages/govuk-frontend/src/govuk/components/header/_index.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@include govuk-exports("govuk/component/header") {
$govuk-header-background: govuk-colour("black");
$govuk-recoloured-header-background: govuk-colour("blue");
$govuk-header-border-color: $govuk-brand-colour;
$govuk-header-border-width: govuk-spacing(2);
$govuk-header-text: govuk-colour("white");
Expand Down Expand Up @@ -352,4 +353,85 @@
}
}
}

.govuk-feature--recolour {
.govuk-header {
border-bottom: 1px solid $govuk-recoloured-header-background;
background: $govuk-recoloured-header-background;
}

.govuk-header__container {
margin-bottom: 0;
padding: 0;
border-bottom: 0;
}

.govuk-header__service-name {
margin: govuk-spacing(2) 0 0;
}

.govuk-header__logo {
@include govuk-responsive-padding($govuk-header-vertical-spacing-value, "top");
}

.govuk-header__navigation {
margin-bottom: 0;
}

.govuk-header__navigation--end {
padding: 0;
}

.govuk-header__navigation-list {
@include govuk-media-query($until: desktop) {
padding-top: govuk-spacing(1);
}
}

.govuk-header__navigation-item {
margin: govuk-spacing(2) 0 govuk-spacing(4);
padding: 0;
border-bottom: 0;

@include govuk-media-query($from: desktop) {
margin: govuk-spacing(3) govuk-spacing(3) 0 0;
padding: 0;
}

a {
@include govuk-typography-weight-regular;
}
}

.govuk-header__navigation-item--active {
border: 0 solid;

@include govuk-media-query($until: desktop) {
margin-left: govuk-spacing(-3);
padding-left: govuk-spacing(2);
border-left-width: govuk-spacing(1);
}

@include govuk-media-query($from: desktop) {
padding-bottom: govuk-spacing(2);
border-bottom-width: govuk-spacing(1);
}

a {
&:link,
&:hover,
&:visited {
color: inherit;
}

&:focus {
color: $govuk-focus-text-colour;
}
}
}

.govuk-header__navigation-item:last-child {
margin-bottom: govuk-spacing(3);
}
}
}

0 comments on commit cd3b5af

Please sign in to comment.