Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cookie consent component #448

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"linebreak-style": 0,
"max-len": [1, 130, 2],
"newline-per-chained-call": ["error", { "ignoreChainWithDepth": 2 }],
"semi": [2, "never"]
"semi": [2, "never"],
"no-new": "off"
},
"env": {
"browser": true,
Expand Down
6 changes: 3 additions & 3 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,14 +315,14 @@ function renamePathForProd() {

function addAnalytics() {
return src(`${config.dir.build}/**/*.html`)
.pipe(inject.after('<head>', `<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
.pipe(inject.after('<head>', `<script data-category="analytics">(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-P2NKBBJZ');</script>
`))
.pipe(inject.after('<head>', `<script async src="https://www.googletagmanager.com/gtag/js?id=G-49T9M12F86"></script>
<script>
.pipe(inject.after('<head>', `<script async data-category="analytics" src="https://www.googletagmanager.com/gtag/js?id=G-49T9M12F86"></script>
<script data-category="analytics">
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
Expand Down
9 changes: 9 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,5 +109,9 @@
"gulp-better-rollup": {
"rollup": "^1||^2||^3"
}
},
"dependencies": {
"@floating-ui/dom": "^1.6.7",
"vanilla-cookieconsent": "^3.0.1"
}
}
1 change: 1 addition & 0 deletions src/components/_all.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
@import 'card/card';
@import 'card-carousel/carousel';
@import 'content-block/content-block';
@import 'cookie-consent/cookie-consent';
@import 'date-input/date-input';
@import 'date-picker/date-picker';
@import 'dialog/dialog';
Expand Down
111 changes: 111 additions & 0 deletions src/components/cookie-consent/_cookie-consent.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
{{#if-equals type "banner"}}
<div class="nsw-cookie-banner js-cookie-banner" role="alert">
<div class="nsw-cookie-banner__wrapper {{#if-equals type "auto opt in"}}js-cookie-banner-auto-opt-in{{else}}js-cookie-banner-opt-in{{/if-equals}}">
<span class="nsw-cookie-banner__main-message">
<div class="nsw-cookie-banner__content">
<div class="nsw-cookie-banner__title">{{title}}</div>
<p>{{{content}}}</p>
</div>
<div class="nsw-cookie-banner__buttons-container">
<button class="nsw-button nsw-button--dark js-cookie-banner-accept">{{#if ctaAccept}}{{ctaAccept}}{{else}}Accept all cookies{{/if}}</button>
{{#if ctaReject}}<button href="{{ctaHref}}" class="nsw-button nsw-button--dark js-cookie-banner-reject">{{#if ctaReject}}{{ctaReject}}{{else}}Reject cookies{{/if}}</button>{{/if}}
<a href="{{urlManageCookies}}" class="nsw-button nsw-button--dark-outline">Manage your cookies</a>
</div>
</span>
{{#if confirmationMessage}}
<span class="nsw-cookie-banner__confirmation-message" hidden="true">
<div class="nsw-cookie-banner__content">
<p>{{{confirmationMessage}}}</p>
</div>
<div class="nsw-cookie-banner__buttons-container">
<button class="nsw-button nsw-button--dark js-cookie-banner-dismiss">Hide this message</button>
</div>
</span>
{{/if}}
</div>
</div>
{{/if-equals}}

{{#if-equals type "dialog"}}
<a href="#{{id}}" class="js-open-dialog-{{id}}" aria-haspopup="dialog">Cookie preferences</a>

<div class="js-cookie-consent nsw-cookie-dialog nsw-dialog{{#unless secondary}} nsw-dialog--single-action{{/unless}} js-dialog{{#if dismiss}} js-dialog-dismiss{{/if}}{{#if active}} active{{/if}}" id="{{id}}" role="dialog" aria-labelledby="{{id}}-title">
<div class="nsw-dialog__wrapper">
<div class="nsw-dialog__container">
<div class="nsw-dialog__top">
<div class="nsw-dialog__title">
<h2 id="{{id}}-title">{{#if title}}{{title}}{{else}}Cookie preferences{{/if}}</h2>
</div>
{{#if dismiss}}
<div class="nsw-dialog__close">
<button class="nsw-icon-button js-close-dialog">
<span class="material-icons nsw-material-icons" focusable="false" aria-hidden="true">close</span>
<span class="sr-only">Close</span>
</button>
</div>
{{/if}}
</div>
<div class="nsw-dialog__content">
<div class="nsw-tabs js-tabs">
<ul class="nsw-tabs__list">
<li><a href="#cookie-settings" class="js-tabs-fixed">Cookie settings</a></li>
<li><a href="#cookie-information" class="js-tabs-fixed">What are cookies?</a></li>
</ul>
<section id="cookie-settings" class="nsw-tabs__content nsw-tabs__content--side-flush">
{{#if content}}{{{content}}}{{else}}<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>{{/if}}
<hr />
<ul class="nsw-cookie-dialog__list">
<li class="nsw-cookie-dialog__list-item">
<input class="nsw-form__checkbox-input" value="analytics" type="checkbox" name="form-checkbox-multi-1" id="cookie-settings-1">
<label class="nsw-form__checkbox-label" for="cookie-settings-1">Marketing cookies (optional)</label>
<div class="nsw-cookie-dialog__cookie-details">
<p>These cookies are used to optimise marketing communications and show you ads on other sites.</p>
</div>
</li>
<li class="nsw-cookie-dialog__list-item">
<input class="nsw-form__checkbox-input" value="foo" type="checkbox" name="form-checkbox-multi-2" id="cookie-settings-2">
<label class="nsw-form__checkbox-label" for="cookie-settings-2">Foo</label>
<div class="nsw-cookie-dialog__cookie-details">
<p>These cookies help us understand how you interact with the site. We use this data to identify areas to improve.</p>
</div>
</li>
</ul>
</section>
<section id="cookie-information" class="nsw-tabs__content nsw-tabs__content--side-flush">
{{#if cookie-information}}{{{cookie-information}}}{{else}}{{/if}}
<p>Cookies are files saved on your phone, tablet or computer when you visit a website.</p>
<p>They store information about how you use the website, such as the pages you visit.</p>
<p>Cookies are not viruses or computer programs. They are very small so do not take up much space.</p>
<h2>How we use cookies</h2>
<p>We use cookies to:</p>
<ul>
<li>make our website work, for example by keeping it secure</li>
<li>remember which pop-ups you've seen</li>
<li>understand how you interact with our website, including tracking the links you click (analytics cookies).</li>
<li>allow you to share pages with social networks like LinkedIn</li>
<li>continuously improve our website for you</li>
</ul>
<p>Also mention if your NSW Government website does or does not collect personal information.</p>
<p>For more information on what cookies are, how they work and how to delete them from your computer, you can visit <a href="https://www.allaboutcookies.org">www.allaboutcookies.org</a>.</p>
</section>
</div>
</div>
</div>
<div class="nsw-cookie-dialog__bottom">
<div class="nsw-cookie-dialog__cta-group">
{{#if savePreferencesBtn}}
<button class="nsw-button nsw-button--dark js-close-dialog" data-role="accept-selection">{{#if savePreferencesBtn}}{{savePreferencesBtn}}{{else}}Accept current selection{{/if}}</button>
{{/if}}
</div>
<div class="nsw-cookie-dialog__cta-group">
{{#if acceptAllBtn}}
<button class="nsw-button nsw-button--dark-outline-solid js-close-dialog" data-role="accept-all">{{#if acceptAllBtn}}{{acceptAllBtn}}{{else}}Accept all cookies{{/if}}</button>
{{/if}}
{{#if acceptNecessaryBtn}}
<button class="nsw-button nsw-button--dark-outline-solid js-close-dialog" data-role="reject-all">{{#if acceptNecessaryBtn}}{{acceptNecessaryBtn}}{{else}}Reject all cookies{{/if}}</button>
{{/if}}
</div>
</div>
</div>
</div>
{{/if-equals}}
179 changes: 179 additions & 0 deletions src/components/cookie-consent/_cookie-consent.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
.nsw-cookie-banner {
padding: rem(24px) 0;
// color: var(--nsw-text-light);
background-color: var(--nsw-status-info-bg);

.nsw-icon-button {
position: absolute;
top: rem(-8px);
right: rem(4px);
// color: var(--nsw-text-light);

&:hover {
@include nsw-hover;
background-color: var(--nsw-hover-light);
}

&:focus {
@include nsw-focus($color: var(--nsw-text-light));
}
}

&__wrapper {
@include container;
position: relative;
}

&__title {
@include font-size('md');
font-weight: var(--nsw-font-bold);
}

&__content {
margin-right: rem(36px);

// a {
// @include link-light;
// }
}

&__buttons-container {
display: flex;
flex-wrap: wrap;
gap: rem(16px);
margin-top: rem(16px);
}

&--light {
background-color: var(--nsw-status-info-bg);
color: var(--nsw-text-dark);

.nsw-cookie-banner__content a {
@include link-dark;
}

.nsw-icon-button {
color: var(--nsw-brand-dark);

&:hover {
background-color: var(--nsw-hover);
}

&:focus {
outline-color: var(--nsw-focus);
}
}
}
}

.nsw-cookie-dialog {
.nsw-dialog__top {
position: sticky;
top: 0;
background: var(--nsw-white);
z-index: 110;
}

&__bottom {
border-top: 1px solid var(--nsw-grey-04);
position: absolute;
bottom: 0;
left: 0;
right: 0;
display: flex;
flex-direction: column;
padding: rem(16px);

@include breakpoint('md') {
flex-direction: row-reverse;
justify-content: space-between;
}

@include breakpoint('lg') {
padding: rem(32px);
}

button {
margin-bottom: rem(16px);

@include breakpoint('md') {
margin-bottom: 0;
}

&:last-child {
margin-bottom: 0;

@include breakpoint('md') {
margin-left: 0;
}
}
}
}

&__cta-group {
display: flex;
gap: rem(16px);

@include breakpoint('md') {
flex-direction: row;
}
}

.nsw-dialog__content {
padding-top: rem(16px);
}

.nsw-tabs__content {
-webkit-overflow-scrolling: auto;
max-height: 320px;
padding-left: 8px;
overflow: scroll;

&:focus-visible {
outline: 2px solid var(--nsw-brand-dark);
border: 0;
}

&:focus {
outline: none;
}

&::-webkit-scrollbar {
width: 8px;
}

&::-webkit-scrollbar-thumb {
border-radius: 4px;
background-color: var(--nsw-grey-03);
box-shadow: 0 0 1px var(--nsw-grey-03);
}
}

&__list {
display: flex;
flex-direction: column;
padding-left: 0;
gap: rem(8px);
}

&__list-item {
display: flex;
flex-direction: column;
gap: rem(8px);

label {
@include font-size('md');
font-weight: var(--nsw-font-bold);
cursor: pointer;
}

&:not(:nth-child(1)) {
border-top: 1px solid var(--nsw-grey-04);
padding-top: rem(28px);
}
}

&__cookie-details {
margin-left: 48px;
}
}
33 changes: 33 additions & 0 deletions src/components/cookie-consent/_guidance.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
title: Cookie banner
layout: blank-layout.hbs
---

<h2>Usage</h2>
<p>Global alerts are designed to capture the attention of the user in a deliberately intrusive way. They persist over a session but are user dismissible, and are purposefully created and not initiated by a user interaction or system event.</p>
<p>Use global alerts:</p>
<ul>
<li>to attract the attention of the user for important messages, or to encourage an action</li>
<li>for messages or actions that are relevant to the entire product or system, not just a feature or page</li>
</ul>
<p>Do:</p>
<ul>
<li>use clear, concise easy to understand language, to minimise cognitive load</li>
<li>use a button or link text in the description to provide users with more information or to complete an action</li>
<li>use at the upper most part of the screen, before the masthead</li>
<li>reserve the use of the critical alert for circumstances which warrant it</li>
</ul>

<h3>Global alert states</h3>
<p>Global alerts are styled according to their purpose:</p>
<ul>
<li><strong>Default alert</strong> - used to show non-critical important information</li>
<li><strong>Critical alert</strong> - used to show critical information</li>
<li><strong>Light alert</strong> - used as an alternative to the blue default on sites where blue features prominently.</li>
</ul>

<h3>When to avoid</h3>
<p>Do not display in response to an action initiated by a user interaction or system event.</p>

<h2>Accessibility</h2>
<p>All components are responsive and meet WCAG 2.1 AA accessibility guidelines.</p>
Loading
Loading