govuk_frontend_toolkit
Advanced tools
| language: node_js | ||
| node_js: | ||
| - "0.10" |
| module.exports = function(grunt) { | ||
| grunt.initConfig({ | ||
| jasmine: { | ||
| javascripts: { | ||
| src: [ | ||
| 'node_modules/jquery-browser/lib/jquery.js', | ||
| 'javascripts/**/*.js', | ||
| ], | ||
| options: { | ||
| specs: 'spec/*Spec.js', | ||
| helpers: 'spec/*Helper.js' | ||
| } | ||
| } | ||
| } | ||
| }); | ||
| grunt.loadNpmTasks('grunt-contrib-jasmine'); | ||
| grunt.registerTask('test', ['jasmine']); | ||
| grunt.registerTask('default', ['test']); | ||
| }; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
| (function() { | ||
| "use strict"; | ||
| window.GOVUK = window.GOVUK || {}; | ||
| var $ = window.$; | ||
| // A multivariate test framework | ||
| // | ||
| // Based loosely on https://github.com/jamesyu/cohorts | ||
| // | ||
| // Full documentation is in README.md. | ||
| // | ||
| function MultivariateTest(options) { | ||
| this.$el = $(options.el); | ||
| this._loadOption(options, 'name'); | ||
| this._loadOption(options, 'customVarIndex'); | ||
| this._loadOption(options, 'cohorts'); | ||
| this._loadOption(options, 'runImmediately', true); | ||
| if (this.runImmediately) { | ||
| this.run(); | ||
| } | ||
| } | ||
| MultivariateTest.prototype._loadOption = function(options, key, defaultValue) { | ||
| if (options[key] !== undefined) { | ||
| this[key] = options[key]; | ||
| } | ||
| if (this[key] === undefined) { | ||
| if (defaultValue === undefined) { | ||
| throw new Error(key+" option is required for a multivariate test"); | ||
| } | ||
| else { | ||
| this[key] = defaultValue; | ||
| } | ||
| } | ||
| }; | ||
| MultivariateTest.prototype.run = function() { | ||
| var cohort = this.getCohort(); | ||
| if (cohort) { | ||
| this.setCustomVar(cohort); | ||
| this.executeCohort(cohort); | ||
| } | ||
| }; | ||
| MultivariateTest.prototype.executeCohort = function(cohort) { | ||
| var cohortObj = this.cohorts[cohort]; | ||
| if (cohortObj.callback) { | ||
| if (typeof cohortObj.callback === "string") { | ||
| this[cohortObj.callback](); | ||
| } | ||
| else { | ||
| cohortObj.callback(); | ||
| } | ||
| } | ||
| if (cohortObj.html) { | ||
| this.$el.html(cohortObj.html); | ||
| this.$el.show(); | ||
| } | ||
| }; | ||
| // Get the current cohort or assign one if it has not been already | ||
| MultivariateTest.prototype.getCohort = function() { | ||
| var cohort = GOVUK.cookie(this.cookieName()); | ||
| if (!cohort || !this.cohorts[cohort]) { | ||
| cohort = this.chooseRandomCohort(); | ||
| GOVUK.cookie(this.cookieName(), cohort, {days: 30}); | ||
| } | ||
| return cohort; | ||
| }; | ||
| MultivariateTest.prototype.setCustomVar = function(cohort) { | ||
| window._gaq = window._gaq || []; | ||
| window._gaq.push([ | ||
| '_setCustomVar', | ||
| this.customVarIndex, | ||
| this.cookieName(), | ||
| cohort, | ||
| 2 // session level | ||
| ]); | ||
| // Fire off a dummy event to set the custom var on the page. | ||
| // Ideally we'd be able to call setCustomVar before trackPageview, | ||
| // but would need reordering the existing GA code. | ||
| window._gaq.push(['_trackEvent', this.cookieName(), 'run', '-', 0, true]); | ||
| }; | ||
| MultivariateTest.prototype.cohortNames = function() { | ||
| return $.map(this.cohorts, function(v, i) { return i; }); | ||
| }; | ||
| MultivariateTest.prototype.chooseRandomCohort = function() { | ||
| var names = this.cohortNames(); | ||
| return names[Math.floor(Math.random() * names.length)]; | ||
| }; | ||
| MultivariateTest.prototype.cookieName = function() { | ||
| return "multivariatetest_cohort_" + this.name; | ||
| }; | ||
| window.GOVUK.MultivariateTest = MultivariateTest; | ||
| }()); |
| #!/bin/bash | ||
| set -e | ||
| npm install | ||
| npm test |
| { | ||
| "name": "govuk_frontend_toolkit", | ||
| "repository": "https://github.com/alphagov/govuk_frontend_toolkit", | ||
| "version": "0.1.0", | ||
| "devDependencies": { | ||
| "grunt": "~0.4.2", | ||
| "grunt-cli": "0.1.11", | ||
| "grunt-contrib-jasmine": "~0.5.2", | ||
| "jquery-browser": "~1.7.2-3" | ||
| }, | ||
| "scripts": { | ||
| "test": "node_modules/.bin/grunt test" | ||
| } | ||
| } |
| describe("MultivariateTest", function() { | ||
| beforeEach(function() { | ||
| GOVUK.cookie = jasmine.createSpy('GOVUK.cookie'); | ||
| window._gaq = []; | ||
| }); | ||
| describe("#run", function() { | ||
| it("should pick a random cohort on first run", function() { | ||
| GOVUK.cookie.andReturn(null); | ||
| var fooSpy = jasmine.createSpy('fooSpy'); | ||
| var barSpy = jasmine.createSpy('barSpy'); | ||
| var test = new GOVUK.MultivariateTest({ | ||
| name: 'stuff', | ||
| customVarIndex: 1, | ||
| cohorts: { | ||
| foo: {callback: fooSpy}, | ||
| bar: {callback: barSpy} | ||
| } | ||
| }); | ||
| expect(GOVUK.cookie.callCount).toEqual(2); | ||
| expect(GOVUK.cookie.argsForCall[1][0]).toEqual('multivariatetest_cohort_stuff'); | ||
| if (GOVUK.cookie.argsForCall[1][1] == 'foo') { | ||
| expect(fooSpy).toHaveBeenCalled(); | ||
| } | ||
| else { | ||
| expect(barSpy).toHaveBeenCalled(); | ||
| } | ||
| }); | ||
| it("should use an existing cohort choice on subsequent runs", function() { | ||
| GOVUK.cookie.andReturn('foo'); | ||
| var fooSpy = jasmine.createSpy('fooSpy'); | ||
| var barSpy = jasmine.createSpy('barSpy'); | ||
| var test = new GOVUK.MultivariateTest({ | ||
| name: 'stuff', | ||
| customVarIndex: 1, | ||
| cohorts: { | ||
| foo: {callback: fooSpy}, | ||
| bar: {callback: barSpy} | ||
| } | ||
| }); | ||
| expect(fooSpy).toHaveBeenCalled(); | ||
| }); | ||
| it("should set a custom var", function() { | ||
| GOVUK.cookie.andReturn('foo'); | ||
| var test = new GOVUK.MultivariateTest({ | ||
| name: 'stuff', | ||
| customVarIndex: 1, | ||
| cohorts: { | ||
| foo: {}, | ||
| bar: {} | ||
| }, | ||
| customVarIndex: 2 | ||
| }); | ||
| expect(window._gaq).toEqual([ | ||
| [ | ||
| '_setCustomVar', | ||
| 2, | ||
| 'multivariatetest_cohort_stuff', | ||
| 'foo', | ||
| 2 | ||
| ], | ||
| [ | ||
| '_trackEvent', | ||
| 'multivariatetest_cohort_stuff', | ||
| 'run', | ||
| '-', | ||
| 0, | ||
| true | ||
| ] | ||
| ]); | ||
| }); | ||
| it("should set html for a cohort", function() { | ||
| GOVUK.cookie.andReturn('foo'); | ||
| var $el = $('<div>'); | ||
| var test = new GOVUK.MultivariateTest({ | ||
| name: 'stuff', | ||
| customVarIndex: 1, | ||
| el: $el, | ||
| cohorts: { | ||
| foo: {html: "foo"}, | ||
| bar: {html: "bar"} | ||
| }, | ||
| }); | ||
| expect($el.html()).toEqual('foo'); | ||
| }); | ||
| it("should call the callback for a cohort", function() { | ||
| var fooSpy = jasmine.createSpy('fooSpy'); | ||
| var barSpy = jasmine.createSpy('barSpy'); | ||
| GOVUK.cookie.andReturn('bar'); | ||
| var $el = $('<div>'); | ||
| var test = new GOVUK.MultivariateTest({ | ||
| name: 'stuff', | ||
| customVarIndex: 1, | ||
| el: $el, | ||
| cohorts: { | ||
| foo: {callback: fooSpy}, | ||
| bar: {callback: barSpy} | ||
| }, | ||
| }); | ||
| expect(barSpy).toHaveBeenCalled(); | ||
| }); | ||
| it("should call the callback for a cohort if it is a string", function() { | ||
| GOVUK.cookie.andReturn('foo'); | ||
| var test = new GOVUK.MultivariateTest({ | ||
| name: 'stuff', | ||
| customVarIndex: 1, | ||
| cohorts: { | ||
| foo: {callback: 'fooCallback'}, | ||
| bar: {} | ||
| }, | ||
| runImmediately: false | ||
| }); | ||
| test.fooCallback = jasmine.createSpy('fooCallback') | ||
| test.run(); | ||
| expect(test.fooCallback).toHaveBeenCalled(); | ||
| }); | ||
| it("should assign a new random cohort if the assigned cohort does not exist", function() { | ||
| var fooSpy = jasmine.createSpy('fooSpy'); | ||
| var barSpy = jasmine.createSpy('barSpy'); | ||
| GOVUK.cookie.andReturn('baz'); | ||
| var test = new GOVUK.MultivariateTest({ | ||
| name: 'stuff', | ||
| customVarIndex: 1, | ||
| cohorts: { | ||
| foo: {callback: fooSpy}, | ||
| bar: {callback: barSpy} | ||
| }, | ||
| }); | ||
| if (GOVUK.cookie.argsForCall[1][1] == 'foo') { | ||
| expect(fooSpy).toHaveBeenCalled(); | ||
| } | ||
| else { | ||
| expect(barSpy).toHaveBeenCalled(); | ||
| } | ||
| }); | ||
| }); | ||
| describe("#cohortNames", function() { | ||
| it("should return the names of the cohorts", function() { | ||
| var test = new GOVUK.MultivariateTest({ | ||
| name: 'stuff', | ||
| customVarIndex: 1, | ||
| cohorts: {foo: {}, bar: {}} | ||
| }); | ||
| expect(test.cohortNames()).toEqual(['foo', 'bar']); | ||
| }); | ||
| }); | ||
| describe("#chooseRandomCohort", function() { | ||
| it("should choose a random cohort", function() { | ||
| var test = new GOVUK.MultivariateTest({ | ||
| name: 'stuff', | ||
| customVarIndex: 1, | ||
| cohorts: {foo: {}, bar: {}} | ||
| }); | ||
| expect(['foo', 'bar']).toContain(test.chooseRandomCohort()); | ||
| }) | ||
| }); | ||
| }); |
| // Measurements used across GOV.UK | ||
| $full-width: 100%; | ||
| $one-quarter: $full-width/4; | ||
| $one-third: $full-width/3; | ||
| $half: $full-width/2; | ||
| $two-thirds: ($full-width)-($one-third); |
| @import "../_colours"; | ||
| @import "../_typography"; | ||
| @import "../_shims"; | ||
| @mixin phase-banner($state: alpha) { | ||
| padding: 8px 0; | ||
| @if $state == alpha { | ||
| background-color: $alpha-colour; | ||
| } @else if $state == beta { | ||
| background-color: $beta-colour; | ||
| } | ||
| p { | ||
| max-width: 960px; | ||
| margin: 0 auto; | ||
| padding: 0 15px; | ||
| color: $text-colour; | ||
| @include core-16; | ||
| } | ||
| a, a:link, a:visited, a:active { | ||
| color: $text-colour; | ||
| } | ||
| a:hover { | ||
| color: $text-colour; | ||
| } | ||
| } | ||
| @mixin phase-tag($state: alpha) { | ||
| @include inline-block; | ||
| @if $state == alpha { | ||
| background-color: $alpha-colour; | ||
| } @else if $state == beta { | ||
| background-color: $beta-colour; | ||
| } | ||
| color: #fff; | ||
| @include bold-16($line-height: 20/16); | ||
| text-transform: uppercase; | ||
| letter-spacing: 1px; | ||
| text-decoration: none; | ||
| margin: 3px 10px 0 5px; | ||
| padding: 2px 5px 0; | ||
| } |
| /* Player overrides */ | ||
| @mixin media-player { | ||
| display: block; | ||
| overflow: hidden; | ||
| margin: 30px 0; | ||
| &.player-wide { | ||
| min-width: 580px; | ||
| } | ||
| span { | ||
| display: block; | ||
| margin: 0; | ||
| padding: 0; | ||
| } | ||
| .video { | ||
| position: relative; | ||
| z-index: 3000; | ||
| iframe { | ||
| display: block; | ||
| } | ||
| } | ||
| .logo { | ||
| display: none; | ||
| } | ||
| .control-bar { | ||
| position: relative; | ||
| width: 100%; | ||
| height: 60px; | ||
| border-bottom: 1px solid $border-colour; | ||
| button { | ||
| background: transparent; | ||
| border: none; | ||
| padding: 0; | ||
| cursor: pointer; | ||
| } | ||
| button, a { | ||
| &:focus { | ||
| background-color: orange; | ||
| outline: none; | ||
| } | ||
| } | ||
| .player-controls { | ||
| .play, .pause { | ||
| position: absolute; | ||
| bottom: 0; | ||
| left: 0; | ||
| width: 40px; | ||
| height: 40px; | ||
| overflow: hidden; | ||
| text-indent: -5000%; | ||
| background-repeat: no-repeat; | ||
| background-position: center left; | ||
| } | ||
| .play { | ||
| background-image: image-url('player-icon-play.png'); | ||
| } | ||
| .pause { | ||
| background-image: image-url('player-icon-pause.png'); | ||
| } | ||
| .rewind, .forward { | ||
| position: absolute; | ||
| top: 0; | ||
| z-index: 30; | ||
| height: 20px; | ||
| width: 40px; | ||
| overflow: hidden; | ||
| text-indent: -5000%; | ||
| background-repeat: no-repeat; | ||
| background-position: center left; | ||
| } | ||
| .rewind { | ||
| left: 0; | ||
| background-image: image-url('player-icon-rewind.png'); | ||
| } | ||
| .forward { | ||
| left: 100%; | ||
| margin-left: -40px; | ||
| background-image: image-url('player-icon-forward.png'); | ||
| } | ||
| } | ||
| .volume-controls { | ||
| position: absolute; | ||
| bottom: 0; | ||
| right: 0; | ||
| height: 40px; | ||
| width: 180px; | ||
| overflow: visible; | ||
| .mute { | ||
| position: absolute; | ||
| bottom: 0; | ||
| left: 120px; | ||
| height: 40px; | ||
| width: 50px; | ||
| padding-top: 1px; | ||
| font-size: 14px; | ||
| line-height: 40px; | ||
| text-align: center; | ||
| } | ||
| .muted { | ||
| color: $light-blue; | ||
| } | ||
| .muted::after { | ||
| content: "d"; | ||
| } | ||
| .muted ~ * { | ||
| opacity: 0.333; | ||
| } | ||
| .vol-down, .vol-up { | ||
| position: absolute; | ||
| bottom: 0; | ||
| height: 40px; | ||
| width: 60px; | ||
| padding-top: 2px; | ||
| font-size: 24px; | ||
| line-height: 40px; | ||
| text-align: center; | ||
| z-index: 10; | ||
| &:hover, &:focus { | ||
| color: $light-blue; | ||
| } | ||
| } | ||
| .vol-down { | ||
| text-align: left; | ||
| padding-left: 10px; | ||
| left: 0; | ||
| } | ||
| .vol-up { | ||
| text-align: right; | ||
| padding-right: 10px; | ||
| left: 60px; | ||
| } | ||
| .vol-display { | ||
| position: absolute; | ||
| bottom: 0; | ||
| left: 20px; | ||
| height: 40px; | ||
| width: 0; | ||
| padding-left: 35px; | ||
| overflow: visible; | ||
| font-size: 14px; | ||
| font-weight: bold; | ||
| line-height: 40px; | ||
| background-repeat: no-repeat; | ||
| background-position: center left; | ||
| background-image: image-url('player-icon-volume.png'); | ||
| } | ||
| .muted ~ .vol-display { | ||
| text-decoration: line-through; | ||
| } | ||
| } | ||
| .current-time { | ||
| position: absolute; | ||
| bottom: 0; | ||
| left: 50px; | ||
| height: 40px; | ||
| font-size: 14px; | ||
| line-height: 40px; | ||
| font-weight: bold; | ||
| } | ||
| .duration-time { | ||
| display: none; | ||
| position: absolute; | ||
| bottom: 0; | ||
| right: 10px; | ||
| height: 40px; | ||
| line-height: 40px; | ||
| font-size: 16px; | ||
| font-weight: bold; | ||
| } | ||
| .ui-slider { | ||
| position: absolute; | ||
| top: 0; | ||
| right: 0; | ||
| width: 100%; | ||
| height: 20px; | ||
| overflow: hidden; | ||
| background: $border-colour; | ||
| .progress-bar { | ||
| position: absolute; | ||
| top: 0; | ||
| left: 0; | ||
| height: 100%; | ||
| padding-bottom: 1px; | ||
| background: $light-blue; | ||
| } | ||
| .ui-slider-handle { | ||
| position: absolute; | ||
| top: 0; | ||
| height: 100%; | ||
| padding-bottom: 1px; | ||
| width: 20px; | ||
| color: rgba(0,0,0,0.5); | ||
| z-index: 10; | ||
| } | ||
| } | ||
| } | ||
| .ui-helper-hidden-accessible { | ||
| position: absolute; | ||
| left: -5000%; | ||
| } | ||
| } |
+1
-1
| [submodule "govuk_frontend_toolkit"] | ||
| path = govuk_frontend_toolkit | ||
| url = git@github.com:alphagov/govuk_frontend_toolkit.git | ||
| url = https://github.com/alphagov/govuk_frontend_toolkit.git |
@@ -8,6 +8,24 @@ # GOV.UK Frontend Toolkit | ||
| If you are going to use the toolkit in a Rails project, we recommend you use the [govuk_frontend_toolkit_gem](https://github.com/alphagov/govuk_frontend_toolkit_gem) and follow the [installation instructions](https://github.com/alphagov/govuk_frontend_toolkit_gem#readme). | ||
| ### Ruby on Rails | ||
| If you are not using a Rails project you can include the toolkit as a [git submodule](https://www.kernel.org/pub/software/scm/git/docs/git-submodule.html). | ||
| We recommend you use the [govuk_frontend_toolkit_gem][toolkit_gem_github] and | ||
| follow the [installation instructions][toolkit_gem_github_readme]. | ||
| [toolkit_gem_github]: https://github.com/alphagov/govuk_frontend_toolkit_gem | ||
| [toolkit_gem_github_readme]: https://github.com/alphagov/govuk_frontend_toolkit_gem#readme | ||
| ### Node.js | ||
| [govuk_frontend_toolkit_npm][toolkit_npm_github] is an NPM package that can be | ||
| [installed or included in your package.json][toolkit_npm]. | ||
| [toolkit_npm_github]: https://github.com/alphagov/govuk_frontend_toolkit_npm | ||
| [toolkit_npm]: https://npmjs.org/package/govuk_frontend_toolkit | ||
| ### Other projects | ||
| You can include the toolkit as a [git submodule][]. | ||
| [git submodule]: https://www.kernel.org/pub/software/scm/git/docs/git-submodule.html | ||
| To add the submodule to your project run the following command substituting the path to a subdirectory in your project's assets directory: | ||
@@ -27,2 +45,9 @@ | ||
| ## Running tests | ||
| Install Node 0.8 or higher and PhantomJS. | ||
| $ npm install | ||
| $ npm test | ||
| ## Usage | ||
@@ -60,2 +85,3 @@ | ||
| * [`design-patterns/_buttons.scss`](#buttons) | ||
| * [`design-patterns/_alpha-beta.scss`](#alpha-beta) | ||
@@ -475,3 +501,3 @@ ### <a id="conditionals"></a>Conditionals | ||
| `@mixin transition($property, $duration, $function)` | ||
| `@mixin transition($property, $duration, $function, $delay:0s)` | ||
@@ -551,3 +577,27 @@ ##### Parameters | ||
| ### <a id="alpha-beta"></a>Alpha/Beta | ||
| Mixins for creating alpha/beta banners and tags for services on GOV.UK | ||
| ##### Description | ||
| `@mixin phase-banner($state)` | ||
| `@mixin phase-tag($state)` | ||
| ##### Parameters | ||
| `$state` either `alpha` or `beta`. This will set the background colour of the element to the appropriate colour. | ||
| ##### Usage | ||
| .alpha-banner { | ||
| @include phase-banner(alpha); | ||
| } | ||
| .beta-banner { | ||
| @include phase-banner(beta); | ||
| } | ||
| .beta-tag{ | ||
| @include phase-tag(beta); | ||
| } | ||
| ## JavaScript | ||
@@ -560,4 +610,72 @@ | ||
| ## Media player | ||
| There is a forked version of the Nomensa video player included and custom | ||
| GOV.UK styles to be used with it. To use it you will need to include the script | ||
| on your page and include the styles nested under an appropriate selector. For | ||
| example: | ||
| @import "design-patterns/media-player"; | ||
| .media-player { | ||
| @include media-player; | ||
| } | ||
| You will also need to create your own initalizer to target the links you want | ||
| to turn into videoss. There are examples of how this works in the [Nomensa | ||
| Accesible Media Player][nomensa] repository. | ||
| [nomensa]: https://github.com/nomensa/Accessible-Media-Player/tree/master/example | ||
| ## Multivariate test framework | ||
| `GOVUK.MultiVariateTest` runs split tests to display different content, layouts etc to users. | ||
| It randomly assigns a user a cohort on first execution by setting a cookie, and on every execution sets a session level custom variable on Google Analytics to mark which cohort a user is in. This can be used to segment users in GA. | ||
| A simple content replacement test can be done by defining a set of cohorts with content. E.g.: | ||
| ```javascript | ||
| var test = new MultivariateTest({ | ||
| el: '.car-tax-button', | ||
| name: 'car_tax_button_text', | ||
| customVarIndex: 555, | ||
| cohorts: { | ||
| pay_your_car_tax: {html: "Pay Your Car Tax"}, | ||
| give_us_money: {html: "Give Us Money Or We Will Crush Your Car"}, | ||
| } | ||
| }); | ||
| ``` | ||
| A more complex test can be done by defining callbacks for what to do | ||
| when a user is in each cohort: | ||
| ```javascript | ||
| var test = new MultivariateTest({ | ||
| name: 'car_tax_button_text', | ||
| customVarIndex: 555, | ||
| cohorts: { | ||
| pay_your_car_tax: {callback: function() { ... }}, | ||
| give_us_money: {callback: function() { ... }}, | ||
| } | ||
| }); | ||
| ``` | ||
| If you have a complex test, it may be worth extending MultivariateTest with | ||
| your own. Callbacks can be strings which will call a method of that name | ||
| on the current object. | ||
| Takes these options: | ||
| - `el`: Element to run this test on (optional) | ||
| - `name`: The name of the text (alphanumeric and underscores) | ||
| - `customVarIndex`: The index of the custom variable in Google Analytics. GA only gives 50 integer slots to each account, and it is important that a unique integer is assigned to each test. Current contact for assigning a custom var slot for GOV.UK is: Ashraf Chohan <ashraf.chohan@digital.cabinet-office.gov.uk> | ||
| - `cohorts`: An object that maps cohort name to an object that defines the cohort. Name must be same format as test name. Object contains keys (both optional): | ||
| - `html`: HTML to fill element with when this cohort is picked. | ||
| - `callback`: Function to call when this cohort is chosen. If it is a string, that method on the test object is called. | ||
| Full documentation on how to design multivariate tests, use the data in GA and construct hypothesis tests is on its way soon. | ||
| ## Licence | ||
| Released under the MIT Licence, a copy of which can be found in the file `LICENCE`. |
@@ -103,1 +103,3 @@ // Colours for the site, as per: | ||
| $page-colour: $white; // The page | ||
| $alpha-colour: $pink; // Alpha badges and banners | ||
| $beta-colour: $orange; // Beta badges and banners |
@@ -32,8 +32,8 @@ /* CSS 3 Mixins | ||
| @mixin transition($property, $duration, $function) { | ||
| -webkit-transition: ($property $duration $function); | ||
| -moz-transition: ($property $duration $function); | ||
| -ms-transition: ($property $duration $function); | ||
| -o-transition: ($property $duration $function); | ||
| transition: ($property $duration $function); | ||
| @mixin transition($property, $duration, $function, $delay: 0s) { | ||
| -webkit-transition: ($property $duration $function $delay); | ||
| -moz-transition: ($property $duration $function $delay); | ||
| -ms-transition: ($property $duration $function $delay); | ||
| -o-transition: ($property $duration $function $delay); | ||
| transition: ($property $duration $function $delay); | ||
| } | ||
@@ -40,0 +40,0 @@ |
@@ -56,3 +56,3 @@ @import '../_shims.scss'; | ||
| &:focus { | ||
| background: darken($colour, 5%); | ||
| background-color: darken($colour, 5%); | ||
| } | ||
@@ -59,0 +59,0 @@ &:active { |
+1
-1
| { | ||
| "name": "govuk_frontend_toolkit", | ||
| "version": "0.12.6", | ||
| "version": "0.41.0", | ||
| "description": "npm for govuk_frontend_toolkit", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
419290
5.33%131
11.97%466
131.84%21
2000%1
Infinity%