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

Rename GOVUKFrontendComponentConfigurable, export ConfigurableComponent #5499

Merged
merged 3 commits into from
Nov 22, 2024
Merged
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
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@ For advice on how to use these release notes see [our guidance on staying up to

## Unreleased

### Use our base configurable component to build your own configurable component

We've added a `ConfigurableComponent` class to help you build your own configurable components. It extends our base component class and so it allows you to focus on your components' specific features by handling these shared behaviours across components:

- checking that GOV.UK Frontend is supported
- checking that the component is not already initialised on its root element
- checking the type of the root element and storing it for access within the component as this.$root
- taking a configuration object as a parameter and then storing it for access within the component as this.config
- merging a passed configuration object with configuration options specified on the data attributes of the root element

We introduced this change in:

- [#5499: Rename GOVUKFrontendComponentConfigurable, export ConfigurableComponent](https://github.com/alphagov/govuk-frontend/pull/5499)
- [#5456: Refactor Accordion to extend from a GOVUKFrontendConfigurableComponent](https://github.com/alphagov/govuk-frontend/issues/5456)

## v5.7.1 (Fix release)

To install this version with npm, run `npm install [email protected]`. You can also find more information about [how to stay up to date](https://frontend.design-system.service.gov.uk/staying-up-to-date/#updating-to-the-latest-version) in our documentation.
Expand Down
1 change: 1 addition & 0 deletions packages/govuk-frontend/src/govuk/all.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export { Tabs } from './components/tabs/tabs.mjs'
export { initAll, createAll } from './init.mjs'
export { isSupported } from './common/index.mjs'
export { GOVUKFrontendComponent as Component } from './govuk-frontend-component.mjs'
export { ConfigurableComponent } from './common/configuration.mjs'

/**
* @typedef {import('./init.mjs').Config} Config
Expand Down
1 change: 1 addition & 0 deletions packages/govuk-frontend/src/govuk/all.puppeteer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ describe('GOV.UK Frontend', () => {
'CharacterCount',
'Checkboxes',
'Component',
'ConfigurableComponent',
'ErrorSummary',
'ExitThisPage',
'Header',
Expand Down
2 changes: 1 addition & 1 deletion packages/govuk-frontend/src/govuk/common/configuration.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const configOverride = Symbol.for('configOverride')
* @template {Element & { dataset: DOMStringMap }} [RootElementType=HTMLElement]
* @augments GOVUKFrontendComponent<RootElementType>
*/
export class GOVUKFrontendComponentConfigurable extends GOVUKFrontendComponent {
export class ConfigurableComponent extends GOVUKFrontendComponent {
/**
* configOverride
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { ConfigError } from '../../errors/index.mjs'
import {
GOVUKFrontendComponentConfigurable,
configOverride
} from '../configuration.mjs'
import { ConfigurableComponent, configOverride } from '../configuration.mjs'

describe('GOVUKFrontendComponentConfigurable', () => {
describe('ConfigurableComponent', () => {
beforeEach(() => {
// Jest does not tidy the JSDOM document between tests
// so we need to take care of that ourselves
Expand All @@ -18,23 +15,23 @@ describe('GOVUKFrontendComponentConfigurable', () => {

describe('throws error', () => {
it('if no schema defined', () => {
class ConfigurableComponent extends GOVUKFrontendComponentConfigurable {
class MockConfigurableComponent extends ConfigurableComponent {
static moduleName = 'config-component'

static defaults = {
randomAttribute: 0
}
}

expect(() => new ConfigurableComponent(document.body)).toThrow(
expect(() => new MockConfigurableComponent(document.body)).toThrow(
new ConfigError(
'config-component: Config passed as parameter into constructor but no schema defined'
)
)
})

it('if no defaults defined', () => {
class ConfigurableComponent extends GOVUKFrontendComponentConfigurable {
class MockConfigurableComponent extends ConfigurableComponent {
static moduleName = 'config-component'

static schema = {
Expand All @@ -44,7 +41,7 @@ describe('GOVUKFrontendComponentConfigurable', () => {
}
}

expect(() => new ConfigurableComponent(document.body)).toThrow(
expect(() => new MockConfigurableComponent(document.body)).toThrow(
new ConfigError(
'config-component: Config passed as parameter into constructor but no defaults defined'
)
Expand All @@ -58,7 +55,7 @@ describe('GOVUKFrontendComponentConfigurable', () => {
<div id="test-component"></div>
`

class ConfigurableComponent extends GOVUKFrontendComponentConfigurable {
class MockConfigurableComponent extends ConfigurableComponent {
static moduleName = 'config-component'

static schema = {
Expand All @@ -74,7 +71,7 @@ describe('GOVUKFrontendComponentConfigurable', () => {

const testComponent = document.querySelector('#test-component')

const configComponent = new ConfigurableComponent(testComponent)
const configComponent = new MockConfigurableComponent(testComponent)

expect(configComponent._config).toMatchObject({ randomAttribute: 0 })
})
Expand All @@ -84,7 +81,7 @@ describe('GOVUKFrontendComponentConfigurable', () => {
<div id="test-component" data-random-attribute="42"></div>
`

class ConfigurableComponent extends GOVUKFrontendComponentConfigurable {
class MockConfigurableComponent extends ConfigurableComponent {
static moduleName = 'config-component'

static schema = {
Expand All @@ -100,7 +97,7 @@ describe('GOVUKFrontendComponentConfigurable', () => {

const testComponent = document.querySelector('#test-component')

const configComponent = new ConfigurableComponent(testComponent)
const configComponent = new MockConfigurableComponent(testComponent)

expect(configComponent._config).toMatchObject({ randomAttribute: 42 })
})
Expand All @@ -110,7 +107,7 @@ describe('GOVUKFrontendComponentConfigurable', () => {
<div id="test-component"></div>
`

class ConfigurableComponent extends GOVUKFrontendComponentConfigurable {
class MockConfigurableComponent extends ConfigurableComponent {
static moduleName = 'config-component'

static schema = {
Expand All @@ -126,7 +123,7 @@ describe('GOVUKFrontendComponentConfigurable', () => {

const testComponent = document.querySelector('#test-component')

const configComponent = new ConfigurableComponent(testComponent, {
const configComponent = new MockConfigurableComponent(testComponent, {
randomAttribute: 100
})

Expand All @@ -138,7 +135,7 @@ describe('GOVUKFrontendComponentConfigurable', () => {
<div id="test-component" data-random-attribute="12"></div>
`

class ConfigurableComponent extends GOVUKFrontendComponentConfigurable {
class MockConfigurableComponent extends ConfigurableComponent {
static moduleName = 'config-component'

static schema = {
Expand All @@ -154,7 +151,7 @@ describe('GOVUKFrontendComponentConfigurable', () => {

const testComponent = document.querySelector('#test-component')

const configComponent = new ConfigurableComponent(testComponent, {
const configComponent = new MockConfigurableComponent(testComponent, {
randomAttribute: 100
})

Expand All @@ -170,7 +167,7 @@ describe('GOVUKFrontendComponentConfigurable', () => {
<div id="test-component" data-random-attribute="13"></div>
`

class ConfigurableComponent extends GOVUKFrontendComponentConfigurable {
class MockConfigurableComponent extends ConfigurableComponent {
[configOverride](config) {
return configOverrideFunction(config)
}
Expand All @@ -190,7 +187,7 @@ describe('GOVUKFrontendComponentConfigurable', () => {

const testComponent = document.querySelector('#test-component')

const configComponent = new ConfigurableComponent(testComponent, {
const configComponent = new MockConfigurableComponent(testComponent, {
randomAttribute: '14'
})

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GOVUKFrontendComponentConfigurable } from '../../common/configuration.mjs'
import { ConfigurableComponent } from '../../common/configuration.mjs'
import { ElementError } from '../../errors/index.mjs'
import { I18n } from '../../i18n.mjs'

Expand All @@ -15,9 +15,9 @@ import { I18n } from '../../i18n.mjs'
* attribute, which also provides accessibility.
*
* @preserve
* @augments GOVUKFrontendComponentConfigurable<AccordionConfig>
* @augments ConfigurableComponent<AccordionConfig>
*/
export class Accordion extends GOVUKFrontendComponentConfigurable {
export class Accordion extends ConfigurableComponent {
/** @private */
i18n

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { GOVUKFrontendComponentConfigurable } from '../../common/configuration.mjs'
import { ConfigurableComponent } from '../../common/configuration.mjs'

const DEBOUNCE_TIMEOUT_IN_SECONDS = 1

/**
* JavaScript enhancements for the Button component
*
* @preserve
* @augments GOVUKFrontendComponentConfigurable<ButtonConfig>
* @augments ConfigurableComponent<ButtonConfig>
*/
export class Button extends GOVUKFrontendComponentConfigurable {
export class Button extends ConfigurableComponent {
/**
* @private
* @type {number | null}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { closestAttributeValue } from '../../common/closest-attribute-value.mjs'
import {
validateConfig,
GOVUKFrontendComponentConfigurable,
ConfigurableComponent,
configOverride
} from '../../common/configuration.mjs'
import { formatErrorMessage } from '../../common/index.mjs'
Expand All @@ -19,9 +19,9 @@ import { I18n } from '../../i18n.mjs'
* of the available characters/words has been entered.
*
* @preserve
* @augments GOVUKFrontendComponentConfigurable<CharacterCountConfig>
* @augments ConfigurableComponent<CharacterCountConfig>
*/
export class CharacterCount extends GOVUKFrontendComponentConfigurable {
export class CharacterCount extends ConfigurableComponent {
/** @private */
$textarea

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GOVUKFrontendComponentConfigurable } from '../../common/configuration.mjs'
import { ConfigurableComponent } from '../../common/configuration.mjs'
import { getFragmentFromUrl, setFocus } from '../../common/index.mjs'

/**
Expand All @@ -8,9 +8,9 @@ import { getFragmentFromUrl, setFocus } from '../../common/index.mjs'
* configuration.
*
* @preserve
* @augments GOVUKFrontendComponentConfigurable<ErrorSummaryConfig>
* @augments ConfigurableComponent<ErrorSummaryConfig>
*/
export class ErrorSummary extends GOVUKFrontendComponentConfigurable {
export class ErrorSummary extends ConfigurableComponent {
/**
* @param {Element | null} $root - HTML element to use for error summary
* @param {ErrorSummaryConfig} [config] - Error summary config
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { GOVUKFrontendComponentConfigurable } from '../../common/configuration.mjs'
import { ConfigurableComponent } from '../../common/configuration.mjs'
import { ElementError } from '../../errors/index.mjs'
import { I18n } from '../../i18n.mjs'

/**
* Exit this page component
*
* @preserve
* @augments GOVUKFrontendComponentConfigurable<ExitThisPageConfig>
* @augments ConfigurableComponent<ExitThisPageConfig>
*/
export class ExitThisPage extends GOVUKFrontendComponentConfigurable {
export class ExitThisPage extends ConfigurableComponent {
/** @private */
i18n

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { GOVUKFrontendComponentConfigurable } from '../../common/configuration.mjs'
import { ConfigurableComponent } from '../../common/configuration.mjs'
import { setFocus } from '../../common/index.mjs'

/**
* Notification Banner component
*
* @preserve
* @augments GOVUKFrontendComponentConfigurable<NotificationBannerConfig>
* @augments ConfigurableComponent<NotificationBannerConfig>
*/
export class NotificationBanner extends GOVUKFrontendComponentConfigurable {
export class NotificationBanner extends ConfigurableComponent {
/**
* @param {Element | null} $root - HTML element to use for notification banner
* @param {NotificationBannerConfig} [config] - Notification banner config
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { closestAttributeValue } from '../../common/closest-attribute-value.mjs'
import { GOVUKFrontendComponentConfigurable } from '../../common/configuration.mjs'
import { ConfigurableComponent } from '../../common/configuration.mjs'
import { ElementError } from '../../errors/index.mjs'
import { I18n } from '../../i18n.mjs'

/**
* Password input component
*
* @preserve
* @augments GOVUKFrontendComponentConfigurable<PasswordInputConfig>
* @augments ConfigurableComponent<PasswordInputConfig>
*/
export class PasswordInput extends GOVUKFrontendComponentConfigurable {
export class PasswordInput extends ConfigurableComponent {
/** @private */
i18n

Expand Down