Skip to content

Commit

Permalink
feat: migrate to exported modules
Browse files Browse the repository at this point in the history
  • Loading branch information
colinrotherham committed Feb 7, 2025
1 parent 9bec43b commit 91ccbf7
Show file tree
Hide file tree
Showing 25 changed files with 365 additions and 288 deletions.
2 changes: 1 addition & 1 deletion docs/assets/javascript/application.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import * as GOVUKFrontend from 'govuk-frontend'

import MOJFrontend from '../../../package/moj/all.js'
import * as MOJFrontend from '../../../src/moj/all.js'

import CollapsibleNav from './collapsible-nav.mjs'
import Cookies from './cookies.mjs'
Expand Down
89 changes: 71 additions & 18 deletions src/moj/all.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
/* eslint-disable no-new */

MOJFrontend.initAll = function (options) {
const { AddAnother } = require('./components/add-another/add-another.js')
const { ButtonMenu } = require('./components/button-menu/button-menu.js')
const { DatePicker } = require('./components/date-picker/date-picker.js')
const {
FilterToggleButton
} = require('./components/filter-toggle-button/filter-toggle-button.js')
const {
MultiFileUpload
} = require('./components/multi-file-upload/multi-file-upload.js')
const { MultiSelect } = require('./components/multi-select/multi-select.js')
const {
PasswordReveal
} = require('./components/password-reveal/password-reveal.js')
const {
RichTextEditor
} = require('./components/rich-text-editor/rich-text-editor.js')
const { SearchToggle } = require('./components/search-toggle/search-toggle.js')
const {
SortableTable
} = require('./components/sortable-table/sortable-table.js')
const { nodeListForEach } = require('./helpers.js')
const { version } = require('./version.js')

function initAll(options) {
// Set the options to an empty object by default if no options are passed.
options = typeof options !== 'undefined' ? options : {}

Expand All @@ -9,15 +32,17 @@ MOJFrontend.initAll = function (options) {
const scope = typeof options.scope !== 'undefined' ? options.scope : document

const $addAnothers = scope.querySelectorAll('[data-module="moj-add-another"]')
MOJFrontend.nodeListForEach($addAnothers, function ($addAnother) {
new MOJFrontend.AddAnother($addAnother)

nodeListForEach($addAnothers, function ($addAnother) {
new AddAnother($addAnother)
})

const $multiSelects = scope.querySelectorAll(
'[data-module="moj-multi-select"]'
)
MOJFrontend.nodeListForEach($multiSelects, function ($multiSelect) {
new MOJFrontend.MultiSelect({

nodeListForEach($multiSelects, function ($multiSelect) {
new MultiSelect({
container: $multiSelect.querySelector(
$multiSelect.getAttribute('data-multi-select-checkbox')
),
Expand All @@ -31,35 +56,43 @@ MOJFrontend.initAll = function (options) {
const $passwordReveals = scope.querySelectorAll(
'[data-module="moj-password-reveal"]'
)
MOJFrontend.nodeListForEach($passwordReveals, function ($passwordReveal) {
new MOJFrontend.PasswordReveal($passwordReveal)

nodeListForEach($passwordReveals, function ($passwordReveal) {
new PasswordReveal($passwordReveal)
})

const $richTextEditors = scope.querySelectorAll(
'[data-module="moj-rich-text-editor"]'
)
MOJFrontend.nodeListForEach($richTextEditors, function ($richTextEditor) {

nodeListForEach($richTextEditors, function ($richTextEditor) {
const options = {
textarea: $($richTextEditor)
}

const toolbarAttr = $richTextEditor.getAttribute(
'data-moj-rich-text-editor-toolbar'
)

if (toolbarAttr) {
const toolbar = toolbarAttr.split(',')

options.toolbar = {}
for (const item in toolbar) options.toolbar[toolbar[item]] = true

for (const item in toolbar) {
options.toolbar[toolbar[item]] = true
}
}

new MOJFrontend.RichTextEditor(options)
new RichTextEditor(options)
})

const $searchToggles = scope.querySelectorAll(
'[data-module="moj-search-toggle"]'
)
MOJFrontend.nodeListForEach($searchToggles, function ($searchToggle) {
new MOJFrontend.SearchToggle({

nodeListForEach($searchToggles, function ($searchToggle) {
new SearchToggle({
toggleButton: {
container: $($searchToggle.querySelector('.moj-search-toggle__toggle')),
text: $searchToggle.getAttribute('data-moj-search-toggle-text')
Expand All @@ -73,19 +106,39 @@ MOJFrontend.initAll = function (options) {
const $sortableTables = scope.querySelectorAll(
'[data-module="moj-sortable-table"]'
)
MOJFrontend.nodeListForEach($sortableTables, function ($table) {
new MOJFrontend.SortableTable({

nodeListForEach($sortableTables, function ($table) {
new SortableTable({
table: $table
})
})

const $datepickers = scope.querySelectorAll('[data-module="moj-date-picker"]')
MOJFrontend.nodeListForEach($datepickers, function ($datepicker) {
new MOJFrontend.DatePicker($datepicker, {}).init()

nodeListForEach($datepickers, function ($datepicker) {
new DatePicker($datepicker, {}).init()
})

const $buttonMenus = scope.querySelectorAll('[data-module="moj-button-menu"]')
MOJFrontend.nodeListForEach($buttonMenus, function ($buttonmenu) {
new MOJFrontend.ButtonMenu($buttonmenu, {}).init()

nodeListForEach($buttonMenus, function ($buttonmenu) {
new ButtonMenu($buttonmenu, {}).init()
})
}

module.exports = {
initAll,
version,

// Components
AddAnother,
ButtonMenu,
DatePicker,
FilterToggleButton,
MultiFileUpload,
MultiSelect,
PasswordReveal,
RichTextEditor,
SearchToggle,
SortableTable
}
14 changes: 8 additions & 6 deletions src/moj/all.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,24 @@

const { getByTestId } = require('@testing-library/dom')

require('./helpers')
require('./all.js')
const { initAll } = require('./all.js')
const {
PasswordReveal
} = require('./components/password-reveal/password-reveal.js')

jest.mock('./components/password-reveal/password-reveal.js')

describe('initAll', () => {
test('initialises container', () => {
MOJFrontend.PasswordReveal = jest.fn()

const container = document.createElement('div')

container.innerHTML = `
<input data-module="moj-password-reveal" data-testid="password-reveal" type="password" />
`

MOJFrontend.initAll({ scope: container })
initAll({ scope: container })

expect(MOJFrontend.PasswordReveal).toHaveBeenCalledWith(
expect(PasswordReveal).toHaveBeenCalledWith(
getByTestId(container, 'password-reveal')
)
})
Expand Down
22 changes: 12 additions & 10 deletions src/moj/components/add-another/add-another.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
MOJFrontend.AddAnother = function (container) {
function AddAnother(container) {
this.container = $(container)

if (this.container.data('moj-add-another-initialised')) {
Expand All @@ -22,7 +22,7 @@ MOJFrontend.AddAnother = function (container) {
.prop('type', 'button')
}

MOJFrontend.AddAnother.prototype.onAddButtonClick = function (e) {
AddAnother.prototype.onAddButtonClick = function (e) {
const item = this.getNewItem()
this.updateAttributes(this.getItems().length, item)
this.resetItem(item)
Expand All @@ -34,23 +34,23 @@ MOJFrontend.AddAnother.prototype.onAddButtonClick = function (e) {
item.find('input, textarea, select').first().focus()
}

MOJFrontend.AddAnother.prototype.hasRemoveButton = function (item) {
AddAnother.prototype.hasRemoveButton = function (item) {
return item.find('.moj-add-another__remove-button').length
}

MOJFrontend.AddAnother.prototype.getItems = function () {
AddAnother.prototype.getItems = function () {
return this.container.find('.moj-add-another__item')
}

MOJFrontend.AddAnother.prototype.getNewItem = function () {
AddAnother.prototype.getNewItem = function () {
const item = this.getItems().first().clone()
if (!this.hasRemoveButton(item)) {
this.createRemoveButton(item)
}
return item
}

MOJFrontend.AddAnother.prototype.updateAttributes = function (index, item) {
AddAnother.prototype.updateAttributes = function (index, item) {
item.find('[data-name]').each(function (i, el) {
const originalId = el.id

Expand All @@ -69,13 +69,13 @@ MOJFrontend.AddAnother.prototype.updateAttributes = function (index, item) {
})
}

MOJFrontend.AddAnother.prototype.createRemoveButton = function (item) {
AddAnother.prototype.createRemoveButton = function (item) {
item.append(
'<button type="button" class="govuk-button govuk-button--secondary moj-add-another__remove-button">Remove</button>'
)
}

MOJFrontend.AddAnother.prototype.resetItem = function (item) {
AddAnother.prototype.resetItem = function (item) {
item.find('[data-name], [data-id]').each(function (index, el) {
if (el.type === 'checkbox' || el.type === 'radio') {
el.checked = false
Expand All @@ -85,7 +85,7 @@ MOJFrontend.AddAnother.prototype.resetItem = function (item) {
})
}

MOJFrontend.AddAnother.prototype.onRemoveButtonClick = function (e) {
AddAnother.prototype.onRemoveButtonClick = function (e) {
$(e.currentTarget).parents('.moj-add-another__item').remove()
const items = this.getItems()
if (items.length === 1) {
Expand All @@ -99,6 +99,8 @@ MOJFrontend.AddAnother.prototype.onRemoveButtonClick = function (e) {
this.focusHeading()
}

MOJFrontend.AddAnother.prototype.focusHeading = function () {
AddAnother.prototype.focusHeading = function () {
this.container.find('.moj-add-another__heading').get(0).focus()
}

module.exports = { AddAnother }
4 changes: 2 additions & 2 deletions src/moj/components/add-another/add-another.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const {
} = require('@testing-library/dom')
const { userEvent } = require('@testing-library/user-event')

require('./add-another.js')
const { AddAnother } = require('./add-another.js')

const user = userEvent.setup()

Expand Down Expand Up @@ -41,7 +41,7 @@ describe('Add Another component', () => {

beforeEach(() => {
component = createComponent()
new MOJFrontend.AddAnother(component)
new AddAnother(component)
addButton = getByRole(component, 'button', { name: 'Add another person' })
})

Expand Down
Loading

0 comments on commit 91ccbf7

Please sign in to comment.