Skip to content

RFC: api proposal #1

Description

@Hotell

this tweet speaks really out for itself, lot of truth in there so let's use it in practice shall we ?! :D
https://twitter.com/housecor/status/938805364442718210?s=17

boardJS api proposal:

  • we don't need mixins like skate ( deep prototype chains meh, for our usecase we wanna use all in )

  • base Component class which should handle

    • async rendering via render()
    • props API ( component public API, immutable ala React )
    • state API ( for internal state ala React )
    • configurable turning on/off for shadowDOM
    • shouldUpdate and willUpdate LC hooks
    • fine grained LC hooks like skates provides ?
    • instance emitter so we don't have to emit(this,'foo',...config) all the time
    • configurable style API ( which will use shadyCSS in non supported browsers)
  • base Component will be created from function mixin which will configure Base component

import {h} from 'preact'
import { withComponent } from 'boardjs'

// standard Component
const Component = withComponent()

// no shadow dom
const NoShadowComponent = withComponent({shadow: false })

// this might be used if consumer want's to use css in js
const NoScopedStyles = withComponent({styleScoping: false})

API

import { withComponent } from 'boardjs'

// standard Component
const Component = withComponent()

type Props = {
  greeting: string
  startTimer: boolean
}
type State = {
  count: number
}

type Events = {
  timerToggle: CustomEvent
}

class Hello extends Component<Props, State, Events> {
  static is = 'x-hello'
  static get props() {
    return {
      greeting: { type: String },
      startTimer: { type: Boolean, reflect: true },
    }
  }
  static get events() {
    return {
      timerToggle: {
        // ...eventConfig  as CustomEventInit -> detail: MyModel // MyModel is a class
      },
    }
  }
  state = {
    count: 0,
  }
  get styles() {
    return `
      :host { display: block; }
      h1 { font-size: 1rem; }
      button { color: white; backgound-color: blue; }
    `
  }
  render() {
    return (
      <div>
        <h1>Hello {this.props.greeting}</h1>
        <div>
          Counter: {this.state.count}
          <br />
          <button onClick={_ => (this.state.count = this.state.count + 1)}>+</button>
          <button onClick={_ => (this.state.count = this.state.count - 1)}>-</button>
          <button onClick={_ => this.events.timerToggle()}>Toggle Timer</button>
        </div>
      </div>
    )
  }

  shouldComponentUpdate(nextProps, nextState) {
    return true
  }
  forceUpdate() {
    // Calling forceUpdate() will cause render() to be called on the component, skipping shouldComponentUpdate()
  }

  // Called when props/state have been set regardless of if they've changed.
  componentWillUpdate() {
    console.log('The component did update')
  }

  // Called if shouldUpdate returned true.
  componentDidUpdate() {
    console.log('The component did update')
  }

  componentWillMount() {
    console.log('The component is gona been rendered')
  }
  componentDidMount() {
    console.log('The component has been rendered')
  }
  componentWillUnmount() {
    console.log('The view is gonna be removed from the DOM')
  }
  componentDidUnmount() {
    console.log('The view has been removed from the DOM')
  }

  componentChildrenDidUpdate() {
    // react to changes to your component's children
  }
}

customElements.define(Hello.is, Hello)

export default Hello

Renderer

  • preact
  • stencil customized preact VDOM ( this would allow us to return arrays from render - win ! )
  • may switch to lit-html when it will have cross browser support

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions