Extension
There are two possible types of extension that can be applied to the framework for Hook components:
  • Extend the types of <Field> element
  • Add a new Element which can be injected in Hook components.
  • <Field> types extension

    #

    Visit example.u.team/extension to try out the live examples.

    In this example, we create a new field type slider based on the rc-slider for temperature input.
    import Slider from 'rc-slider'
    const mySlider = param => {
        const { value, isRead, onChange, props } = param
        props.disabled = isRead || props.disabled
        return <Slider  {...props} value={value}
            onChange={value => onChange({ target: { value } })} />}

    const myExtension = _this => {
        _this.customfield = { ..._this.customfield, slider: mySlider }
    }

    // Replace utCreateElement
    const myCreateElement = props => {
        props.param = { ...props.param, extend: myExtension }
        return utCreateElement(props)}

    export default myCreateElement({ reducer, layout })

  • Create a mySlider component for interfacing the imported Slider.
  • Add ‘slider’ as a new type to the customfield object in the myExtension function.
  • Define a myCreateElement to replace utCreateElement by assigning myExtension to props.param.extend property.
  • Schema

    #
    import Slider from 'rc-slider'
    const reducer = utReducer('react-example/extend-userHook', {
        init: {
            ...
            fields: {
                ...
                temperature: {type: 'slider', value: 28}
        },}
    })

    Layout

    #
    const layout = ({ _, Field, Memo }) => <>
        Slider control added as field type 'slider',
        you can pass custom properties through the <Field> element
        <Field id='temperature' marks={{
            10: {label: 'low'}, 50: {label: 'high'}}} />
        <p>Input temperature: {_.fields.temperature.value}</p>
    </>
  • marks is the property that will be passed to the rc-slider component.
  • Component Extension

    #


    In this example, we create a new component Memo using the Toast imported from React Bootstrap.
    import { Toast } from 'react-bootstrap'
    const myMemo = _this => ({ title }) => {
        const { _ } = _this.props.init
        return <Toast>
            <Toast.Header>
                <img src="/assets/icons/favicon.png"
                     width='20px' className="rounded me-2" alt="" />
                <strong className="me-auto">{title}</strong>
                <small>11 mins ago</small>
            </Toast.Header>
            <Toast.Body>Hello, world! This is a toast message.
                <div>Name entered: {_.fields.name.value}</div>
            </Toast.Body>
        </Toast>
    }

  • title is the only property for this component.
  • _this.props.init is the object used to retrieve the _ state object.
  • _.fields.name.value can be used to access the field value.

  • const myExtension = _this => {
        _this.Memo = myMemo(_this)
        return { Memo: _this.Memo }
    }

    const myCreateElement = props => {
        props.param = { ...props.param, extend: myExtension }
        return utCreateElement(props)}

    export default myCreateElement({ reducer, layout })
  • Add Memo to the _this object
  • Return { Memo: _this.Memo }
  • Layout

    #
    const layout = ({ _, Field, Memo }) => <>
        ...
        <Memo title='My extended component' />
    </>
  • The new Memo element is being injected as layout properties.
  • Use it with a custom title.