Skip to content

bluejsx/docs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Documentation

For Typescript coders, please see bluejsx TS doc after finish reading this page.

Basic

The usage of VanillaJSX is simple!

native HTML elements

const elem1 = <div id='elem1'>hi!</div>

↑This will work as:

const elem1 = document.createElement('div')
elem1.id = 'elem1'
elem1.append('hi!')

FYI

  • Blue sets attributes as IDL attributes.
  • This means Blue uses elem['attrName']='value' instead of elem.setAttribute('attrName', 'value')
    • This makes you able to set HTML properties such as innerHTML and onclick.
    • Exceptions:
      • SVG elements
      • class and style attribute
      • attributes that include dash -

Function components

You can make components with functions.

  • Your function components:
    • can take attributes as function parameters
      • children elements via children parameter
    • need to return Element.
    • runs only once.
const App = ({ name, children }) =>{
  const self = <div>
    Hello, {name}!
    <hr>
    {children}
  </div>
  return self
}

document.querySelector('#app').appendChild(
  <App name='VanillaJSX'>
    <div>This is child element</div>
  </App>)

Ref Attribute

You can avoid breaking down DOM trees. By using ref attribute, you can replace the following code:

const btn = <button>click</button>
const progress = <progress max='10' value='0' />
const self = (
  <div>
    {btn}
    {progress}
  </div>
)
btn.onclick = () => progress.value++

with:

const refs = {}
const self = (
  <div>
    <button ref={[refs, 'btn']}>click</button>
    <progress ref={[refs, 'progress']} max='10' value='0' />
  </div>
)
const { btn, progress } = refs
btn.onclick = () => progress.value++

Here is the usage:

First, make a new empty object:

const refs = {}

Next, add ref attribute to your element, and set the following array:

<button ref={[refs, 'btn']}>

After the Element declarations, add following code:

const { btn } = ref

Great! You can now be able to use the button element with the btn variable. Don't forget, the value of ref attribute is:

[object, string]
//[<object for reference passing>, <name of the element you prefer to use>]

Text setter

You can use Text object (which is defined natively on browser) to change DOM texts dynamically.

const countText = new Text('0')
<div onclick={()=>countText.data++}>
  count: {countText}!!!
</div>

The element above counts up the number of clicking of the element.

Dynamic Attributes

Blue provides useAttr function:

import { useAttr } from 'bluejsx'
useAttr(elem: AttrHolder, propName: string, defaultValue: any)
  • This defines custom property setter/getter on your element.
  • You are able to listen the value change using watch listener:
    elem.watch(propName: string, (newValue) => void)
    • watch listener is similar to addEventListener
    • The difference is that the listener function in watch recieves the new property value, not Event object.

Example:

import { useAttr } from 'bluejsx'

const Example = ({progValue=0, children})=>{
  const progress = <progress max='100' value={progValue}/>
  const btn = <button>click</button>
  const self = (
    <div class='t3'>
      {btn}
      {progress}
      {children}
    </div>
  )
  useAttr(self, 'progValue', progValue)
  self.watch('progValue', v=> progress.value = v)

  btn.onclick = () =>{
    /*
      below just looks assigning a value to a property,
      however this is running getter/setter method,
      which executes all listener functions registered via `watch` method.
    */
    if(self.progValue<100) self.progValue+=10
    else self.progValue = 0
  }
  return self	
}

If you want to use Protected Attributes (States)

You can use AttrHolder object:

import { useAttr, AttrHolder } from 'bluejsx'

const state = new AttrHolder()

useAttr(state, 'attr1', 0)
state.watch('attr1', v=> console.log(v))

state.attr1 = 50

This would be useful when you want to make private attributes, which can't be accesed outside of your function component.

Custom Element components

This is VanillaJS way to implement custom HTML elements. For details see CustomElement Documentation

Example:

class CustomProgress extends HTMLElement{
  #max = 1
  #value = null
  #bar
  constructor(...args){
    super(...args);
    this.#bar = <div part='bar'/>
    const shadow = this.attachShadow({mode: 'closed'})
    shadow.appendChild(this.#bar);
  }
  static get observedAttributes(){
    return ['max', 'value'];
  }
  connectedCallback(){
    this.render()
  }
  attributeChangedCallback(name, oldValue, newValue) {
    switch(name){
      case 'max':
        this.#max = +newValue
        this.render()
        break;
      case 'value':
        this.#value = Math.min(this.#max, newValue)
        this.render()
        break;
      default:
        break;
    }
  }
  render(){
    if(this.#value){
      this.classList.remove('indeterminate')
      if(this.#value === this.#max) this.classList.add('complete')
      const r = this.#value / this.#max * 100
      this.#bar.style.width = r+'%';
    }else{
      this.#bar.style.width=''
      this.classList.remove('complete')
      this.classList.add('indeterminate')
    }
  }
  get value(){
    return this.#value
  }
  get max(){
    return this.#max
  }
  set value(v){
    this.setAttribute('value',v)
  }
  set max(max){
    this.setAttribute('max',max)
  }
}
customElements.define('custom-progress',CustomProgress)
export default CustomProgress

In this case, you can use either

<custom-progress />

or

<CustomProgress />

Tips

Since you load VanillaJSX in your javascript, on method, a shorthand of addEventListener is available on all the objects which provide addEventListener method (i.e. EventTarget objects).

This can be simply implemented by the code below:

EventTarget.prototype.on = EventTarget.prototype.addEventListener

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published