Skip to content

Commit

Permalink
refactor(date picker): refactor date picker template to be cleaner
Browse files Browse the repository at this point in the history
The previous template resulted in nested moj-form-group elements causing issues with error states.
The template has now been refactored to more fully utilise the govuk-input macro and  use the
govuk-attributes macro too to impriove and simplify the external api to the component.
  • Loading branch information
chrispymm committed Jul 11, 2024
1 parent 01b498e commit 3fa2db0
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 92 deletions.
2 changes: 1 addition & 1 deletion docs/components/date-picker.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ Multiple date picker components can be horizontally displayed. This is useful wh

Follow the guidance in the [GOV.UK Design System](https://design-system.service.gov.uk/components/error-message/) for error messages.

{% example "/examples/date-picker", 590 %}
{% example "/examples/date-picker-error", 590 %}

### Error messages in English and Welsh

Expand Down
21 changes: 21 additions & 0 deletions docs/examples/date-picker-error/index.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
layout: layouts/example.njk
title: Date Picker (example)
arguments: date-picker
---

{%- from "moj/components/date-picker/macro.njk" import mojDatePicker -%}

{{ mojDatePicker({
id: "date",
name: "date",
label: {
text: "Date"
},
hint: {
text: "For example, 17/5/2024."
},
errorMessage: {
text: 'Enter or pick a date'
}
}) }}
14 changes: 7 additions & 7 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"clipboard": "^2.0.8",
"del": "^7.0.0",
"esbuild": "^0.23.0",
"govuk-frontend": "^5.0.0",
"govuk-frontend": "^5.4.0",
"gulp": "^4.0.2",
"gulp-cache": "^1.1.3",
"gulp-concat": "^2.6.1",
Expand Down
75 changes: 66 additions & 9 deletions src/moj/components/date-picker/_date-picker.scss
Original file line number Diff line number Diff line change
Expand Up @@ -177,21 +177,78 @@

}

.moj-datepicker-input-wrapper {
position: relative;
display: flex;
margin-bottom: 24px;
overflow: visible;
/*
Default input with to .govuk-input--width-10 (10 chars)
Allow that to be overriden by the input width modifiers or global width overrides.
Width classes less than 10ch not included as that is narrower than a date.
*/
.moj-datepicker input {
max-width: 11.5em; // govuk-input--width-10

&.govuk-input--width-30 {
max-width: 29.5em;
}

&.govuk-input--width-20 {
max-width: 20.5em;
}

&.govuk-\!-width-full {
width: 100% !important;
max-width: none;
}

> .govuk-form-group {
width: 100%;
&.govuk-\!-width-three-quarters {
width: 100% !important;
max-width: none;

@include govuk-media-query($from: tablet) {
width: 75% !important;
}
}

&--fixed > .govuk-form-group {
width: auto;
&.govuk-\!-width-two-thirds {
width: 100% !important;
max-width: none;

@include govuk-media-query($from: tablet) {
width: 66.66% !important;
}
}

&.govuk-\!-width-one-half {
width: 100% !important;
max-width: none;

@include govuk-media-query($from: tablet) {
width: 50% !important;
}
}

&.govuk-\!-width-one-third {
width: 100% !important;
max-width: none;

@include govuk-media-query($from: tablet) {
width: 33.33% !important;
}
}

&.govuk-\!-width-one-quarter {
width: 100% !important;
max-width: none;

@include govuk-media-query($from: tablet) {
width: 25% !important;
}
}
}

.moj-datepicker__wrapper {
position: relative;
}


@media (min-width: 768px) {
.moj-datepicker-dialog {
width: auto;
Expand Down
42 changes: 26 additions & 16 deletions src/moj/components/date-picker/date-picker.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,18 @@ Datepicker.prototype.initControls = function () {

this.dialogElement = dialog
this.createCalendarHeaders()
this.$input.insertAdjacentElement('afterend', this.dialogElement)
this.$input.parentElement.insertAdjacentHTML('afterend', this.createToggleMarkup() )

const pickerWrapper = document.createElement('div')
const inputWrapper = document.createElement('div')
pickerWrapper.classList.add('moj-datepicker__wrapper')
inputWrapper.classList.add('govuk-input__wrapper')

this.$input.parentNode.insertBefore(pickerWrapper, this.$input)
pickerWrapper.appendChild(inputWrapper)
inputWrapper.appendChild(this.$input)

inputWrapper.insertAdjacentHTML('beforeend', this.createToggleMarkup() )
pickerWrapper.insertAdjacentElement('beforeend', this.dialogElement)

this.$calendarButton = this.$module.querySelector('.moj-js-datepicker-toggle')
this.dialogTitleNode = this.dialogElement.querySelector('.moj-js-datepicker-month-year')
Expand Down Expand Up @@ -261,24 +271,24 @@ Datepicker.prototype.setOptions = function() {
}

Datepicker.prototype.setMinAndMaxDatesOnCalendar = function () {
if (this.$input.dataset.mindate) {
this.minDate = this.formattedDateFromString(this.$input.dataset.mindate, null)
if (this.$module.dataset.mindate) {
this.minDate = this.formattedDateFromString(this.$module.dataset.mindate, null)
if (this.minDate && this.currentDate < this.minDate) {
this.currentDate = this.minDate
}
}

if (this.$input.dataset.maxdate) {
this.maxDate = this.formattedDateFromString(this.$input.dataset.maxdate, null)
if (this.$module.dataset.maxdate) {
this.maxDate = this.formattedDateFromString(this.$module.dataset.maxdate, null)
if (this.maxDate && this.currentDate > this.maxDate) {
this.currentDate = this.maxDate
}
}
}

Datepicker.prototype.setDisabledDates = function() {
if(this.$input.dataset.disableddates) {
this.disabledDates = this.$input.dataset.disableddates
if(this.$module.dataset.disableddates) {
this.disabledDates = this.$module.dataset.disableddates
.replace(/\s+/, ' ')
.split(' ')
.map((item) => {
Expand All @@ -304,15 +314,15 @@ Datepicker.prototype.setDisabledDates = function() {
}

Datepicker.prototype.setDisabledDays = function () {
if (this.$input.dataset.disableddays) {
if (this.$module.dataset.disableddays) {
// lowercase and arrange dayLabels to put indexOf sunday == 0 for comparison
// with getDay() function
let weekDays = this.dayLabels.map(item => item.toLowerCase())
if(this.config.weekStartDay === 'monday') {
weekDays.unshift(weekDays.pop())
}

this.disabledDays = this.$input.dataset.disableddays
this.disabledDays = this.$module.dataset.disableddays
.replace(/\s+/, ' ')
.toLowerCase()
.split(' ')
Expand All @@ -322,23 +332,23 @@ Datepicker.prototype.setDisabledDays = function () {
}

Datepicker.prototype.setLeadingZeros = function() {
if (this.$input.dataset.leadingzeros) {
if(this.$input.dataset.leadingzeros.toLowerCase() === 'true') {
if (this.$module.dataset.leadingzeros) {
if(this.$module.dataset.leadingzeros.toLowerCase() === 'true') {
this.config.leadingZeros = true;
}
if(this.$input.dataset.leadingzeros.toLowerCase() === 'false') {
if(this.$module.dataset.leadingzeros.toLowerCase() === 'false') {
this.config.leadingZeros = false;
}
}
}

Datepicker.prototype.setWeekStartDay = function() {
const weekStartDayParam = this.$input.dataset.weekstartday;
if(weekStartDayParam.toLowerCase() === 'sunday' ) {
const weekStartDayParam = this.$module.dataset.weekstartday;
if(weekStartDayParam?.toLowerCase() === 'sunday' ) {
this.config.weekStartDay = 'sunday'
this.dayLabels.unshift(this.dayLabels.pop())
}
if(weekStartDayParam.toLowerCase() === 'monday' ) {
if(weekStartDayParam?.toLowerCase() === 'monday' ) {
this.config.weekStartDay = 'monday'
}
}
Expand Down
98 changes: 40 additions & 58 deletions src/moj/components/date-picker/template.njk
Original file line number Diff line number Diff line change
@@ -1,68 +1,50 @@
{% from "govuk/components/input/macro.njk" import govukInput %}
{% from "govuk/components/label/macro.njk" import govukLabel %}
{% from "govuk/components/hint/macro.njk" import govukHint %}
{% from "govuk/components/error-message/macro.njk" import govukErrorMessage %}
{% from "govuk/macros/attributes.njk" import govukAttributes %}

<div class="govuk-form-group {{ 'govuk-form-group--error' if params.errorMessage }} moj-datepicker {{ params.classes }}" data-module="moj-date-picker">
{{ govukLabel({
html: params.label.html,
text: params.label.text,
classes: params.label.classes,
isPageHeading: params.label.isPageHeading,
attributes: params.label.attributes,
for: params.id
}) | indent(2) | trim }}
{% if params.hint %}
{% set hintId = params.id + "-hint" %}
{% set describedBy = describedBy + " " + hintId if describedBy else hintId %}
{{ govukHint({
id: hintId,
classes: params.hint.classes,
attributes: params.hint.attributes,
html: params.hint.html,
text: params.hint.text
}) | indent(2) | trim }}
{% endif %}
{% if params.errorMessage %}
{% set errorId = params.id + "-error" %}
{% set describedBy = describedBy + " " + errorId if describedBy else errorId %}
{{ govukErrorMessage({
id: errorId,
classes: params.errorMessage.classes,
attributes: params.errorMessage.attributes,
html: params.errorMessage.html,
text: params.errorMessage.text,
visuallyHiddenText: params.errorMessage.visuallyHiddenText
}) | indent(2) | trim }}
{% endif %}

{% set fixedWidth = true %}
{% set widthClass = 'govuk-input--width-10' %}
{% set classNames = "moj-js-datepicker-input " %}

{% if params.inputWidthClass == '' %}
{% set fixedWidth = false %}
{% set widthClass = '' %}
{% elif params.inputWidthClass %}
{% set fixedWidth = true %}
{% set widthClass = params.inputWidthClass %}
{% endif %}
<div class="moj-datepicker-input-wrapper {% if fixedWidth %}
moj-datepicker-input-wrapper--fixed {% endif %}">
{%- if params.classes %}
{% set classNames = classNames + " " + params.classes %}
{% endif %}

{% set attributes = {
"data-module": 'moj-date-picker',
"data-mindate": {
value: params.mindate,
optional: true
},
"data-maxdate": {
value: params.maxdate,
optional: true
},
"data-disableddates": {
value: params.disabledDates,
optional: true
},
"data-disableddays": {
value: params.disabledDays,
optional: true
},
"data-leadingzeros": {
value: params.leadingZeros,
optional: true
},
"data-weekstartday": {
value: params.weekStartDay,
optional: true
}
} %}

<div class="moj-datepicker" {{ govukAttributes(attributes) }}>
{{ govukInput({
classes: "govuk-input moj-js-datepicker-input " + widthClass,
classes: classNames,
id: params.id,
name: params.name,
value: params.value,
describedBy: hintId if params.hint,
autocomplete: "off",
attributes: {
"data-mindate": params.minDate,
"data-maxdate": params.maxDate,
"data-disableddates": params.disabledDates,
"data-disableddays": params.disabledDays,
"data-leadingzeros": params.leadingZeros,
"data-weekstartday": params.weekstartday
}
formGroup: params.formGroup,
label: params.label,
hint: params.hint,
errorMessage: params.errorMessage
}) }}
</div>
</div>

0 comments on commit 3fa2db0

Please sign in to comment.