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

Add helper for creating DOM elements #2894

Open
2 tasks
romaricpascal opened this issue Oct 3, 2022 · 5 comments
Open
2 tasks

Add helper for creating DOM elements #2894

romaricpascal opened this issue Oct 3, 2022 · 5 comments

Comments

@romaricpascal
Copy link
Member

What

Add a createElement (naming up for discussion) helper function to act as a shortcut for creating elements and assigning them attributes, props and/or children (scope to be defined). Something along the lines of the following (in a syntax more adapted to the browsers we support):

export function createElement (tagName, {attributes = {}, properties = {}, children = []} = {}) {
  const el = document.createElement(tagName)

  Object.entries(attributes).forEach(([attributeName, attributeValue]) => {
    el.setAttribute(attributeName, attributeValue)
  })
  
  // This can help set `innerHTML` for example
  Object.entries(properties).forEach(([propertyName, propertyValue) => {
  	el[propertyName] = propertyValue
  })

  children.forEach(child => {
    el.appendChild(child)
  })

  return el
}

Why

A lightweight version of such helper has been added to de-clutter tests for the CharacterCount internationalisation: https://github.com/alphagov/govuk-frontend/blob/character-count-i18n/lib/dom-helpers.mjs. The Accordion and CharacterCount create a few elements themselves when initialised which would get a bit leaner.

Who needs to work on this

Developers

Who needs to review this

Developers

Done when

  • Decision on whether the helper would be helpful is made
  • If positive, helper is added and used in the component's code
@romaricpascal
Copy link
Member Author

Linking @36degrees' comment on the PR that sparked the creation of this issue: https://github.com/alphagov/govuk-frontend/pull/2887/files#r983699156.

@romaricpascal
Copy link
Member Author

A further note that the dom-helpers.mjs file has gained a second helper to create a DocumentFragment out of an HTML String to scaffold larger structures, that's worth discussing at the same time:

export function createFragmentFromHTML (html) {
  const template = document.createElement('template')
  template.innerHTML = html
  return template.content.cloneNode(true)
}

romaricpascal added a commit that referenced this issue Oct 10, 2022
Waiting for further discussion about abstraction in #2894
romaricpascal added a commit that referenced this issue Oct 10, 2022
Waiting for further discussion about abstraction in #2894
romaricpascal added a commit that referenced this issue Oct 11, 2022
Waiting for further discussion about abstraction in #2894
romaricpascal added a commit that referenced this issue Oct 11, 2022
Waiting for further discussion about abstraction in #2894
querkmachine pushed a commit that referenced this issue Oct 17, 2022
Waiting for further discussion about abstraction in #2894
@querkmachine querkmachine added feature request User requests a new feature javascript tooling and removed awaiting triage Needs triaging by team labels Apr 26, 2023
@romaricpascal
Copy link
Member Author

romaricpascal commented Jun 10, 2024

Missed to share that I had explored the concept of creating elements in a more thorough way outside of govuk-frontend at the time. There may be useful code in there we could look at.

@36degrees
Copy link
Contributor

Having spent a bit of time looking at the JavaScript for the accordion recently I can see more of a need for this than maybe I appreciated before.

I've pushed a branch with a commit that shows what it might look like in practise (although just accepting attributes for now) in case it's useful in the future: 13ef8cd

@romaricpascal
Copy link
Member Author

Probably one step too far, but given our tool chain has Babel set up to compile our sources, we could use the transform-react-jsx plugin to automatically transform JSX markup into a createElement calls 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants