BUILDING WEB COMPONENTS WITH VANILLA JAVASCRIPT

Plain JavaScript without any additional libraries like jQuery and without new, fancy frameworks

Lightweight, fast, easy to maintain, reusable

Hyper-modular structure (many tiny components doing one thing)

module.exports = inputInteger

// CREATING STYLESHEET PER COMPONENT
// reusing one stylesheet in every component instance
const sheet = new CSSStyleSheet
const theme = get_theme()
sheet.replaceSync(theme)


// COMPONENT LOGIC
function inputInteger (opts) {
  const el = document.createElement('div')
  const shadow = el.attachShadow({ mode: 'closed' })

  const input = document.createElement('input')
  input.type = 'number'

  input.onkeyup = (e) => handle_onkeyup(e, input, min, max)
  input.onmouseleave = (e) => handle_onmouseleave_and_blur(e, input, min)
  input.onblur = (e) => handle_onmouseleave_and_blur(e, input, min)

  shadow.append(input)
  
  shadow.adoptedStyleSheets = [sheet, opts.custom_sheet]
  return el
}

// THEME/CSS
function get_theme () {
  return `
    input {
      color: pink;
      background-color: grey;
    }
  `
}
var id = 0

function inputInteger (opts, protocol) {

  const name = `input-integer-${id++}`
  const notify = protocol({ from: name }, listen)
  
  function listen (message) {
    const { type, data } = message
    if (type === 'update') {
      input.value = data
    }
  }
 
  const el = document.createElement('div')
  const shadow = el.attachShadow({ mode: 'closed' })

  const input = document.createElement('input')
  input.type = 'number'

  input.onkeyup = (e) => handle_onkeyup(e, input, min, max)
  input.onmouseleave = (e) => handle_onmouseleave_and_blur(e, input, min)
  input.onblur = (e) => handle_onmouseleave_and_blur(e, input, min)

  shadow.append(input)
  shadow.adoptedStyleSheets = [sheet, opts.custom_sheet]
  return el
}
const inputInteger = require('inputInteger')

function form () {
  const state = {}

  const sheet = new CSSStyleSheet
  const theme = get_theme()
  sheet.replaceSync(theme)

  const input = inputInteger({ custom_sheet: sheet }, protocol)

  function protocol (message, notify) {
    const { from } = message
    state[from] = { value: 0, notify }
    return listen
  }

  function listen (message) {
    const { from, type, data } = message
    state[from].value = data
    if (type === 'update') {
      const notify = state['input-integer-0'].notify
      notify({ type, data })
    }
  }
  
  return input
}

function get_theme () {
  return ` input {  color: magenta;} `
}


document.body.append(form())

Workshops:

How to build & compose web components 

Made with Slides.com