Skip to content

Documentation - React binding

The binding for React comes as a set of higher order components which basically link a smart-table directive to your component so you don't have to take care of the subscriptions or the updates and can focus on the view part only

See the example CodePen. A more complete example should be available on the project repository.

Usage

The package itself is "framework agnostic". It means it should work for any react like framework such as Preact. However you will need to initialize the module with the framework you use.

Initialise with React

Just pass the React namespace

import React from 'react';
import factory from 'smart-table-react';

export default factory(React);

Initialise with Preact

Map method names (technically you only need the Component class and the createElement method equivalents)

import factory from 'smart-table-react';
import {h, Component} from 'preact';

export default factory({createElement: h, Component});

You can then use the exported object everywhere in your application. The rest of the documentation will assume the exported module is in the smart-table.js file.

Conventions

As mentioned the produced higher order components will be built around the regular smart table directives with the following conventions

Detailed HOC

Table HOC

This HOC should help you to create the root component. It will expose the currently displayed collection as the displayed property.

The only (and mandatory) configuration attribute will be the instance of your smart table.

import React from 'react';
import ReactDom from 'react-dom';
import reactSt from './smart-table.js';
import {smartTable as st} from 'smart-table-core';

// your row component
const Row = ({value}) => {
  const {surname, name}=value;
  return (<tr>
    <td>{surname}</td>
    <td>{name}</td>
  </tr>);
};

// your body component (connected to the smart table)
// note the usage of the table hoc
const TableBody = reactSt.table((props) => {
  const {stState} = props;
  const displayed = stState.length ? stState : [];
  return (<tbody>
  {displayed.map(({value, index}) => {
    return <Row key={index} value={value}/>
  })}
  </tbody>);
});


// mount it somewhere with your smart table
const table = st({
  data: [
    {surname: 'Renard', name: 'Laurent'},
    {surname: 'Leponge', name: 'Bob'}
  ]
});

ReactDom.render(
  <table>
    <thead>
    <tr>
      <th>Surname</th>
      <th>Name</th>
    </tr>
    </thead>
    <TableBody smartTable={table}/>
  </table>
  , document.getElementById('table-container'));

That is it now your rows will be updated whenever the table state change.

Sort HOC

This hoc will help you to use the sort directive within your component.

Configurations attributes

smartTable
The instance of smart table
stSort
The pointer to the sorted property
stSortCycle
Whether the toggle will cycle through the 3 sort states or simply pass from ascending sort to descending sort only (default to false)

Example

Here is an example of sortable header which will toggle the sort state when clicked and will change its class name based on the current sort state

import React from 'react';
import reactSt from './smart-table.js';

// your pure component
function Header (props) {
  const {stSort, stDirective, stState, children} = props;
  const {pointer, direction} = stState;
  let className = '';
  if (pointer === stSort) {
    if (direction === 'asc') {
      className = 'st-sort-asc';
    } else if (direction === 'desc') {
      className = 'st-sort-desc';
    }
  }
  return <th className={className} onClick={stDirective.toggle}>{children}</th>;
}

//note the use of the sort HOC
const SortableHeader = reactSt.sort(Header);

/*
to be used like

...

 <tr>
   <SortableHeader smartTable={t} stSort="surname" stSortCycle={true}>Surname</SortableHeader>
   <SortableHeader smartTable={t} stSort="name">Name</SortableHeader>
 </tr>

...

 */

Search HOC

This hoc will help you to use the search directive by creating controlled search input

Configuration attributes

smartTable
The instance of smart table
stSearchScope
An array of pointers which will define the search scope

Example

An example of a search input which will trigger a search whenever the input value changes

import React from 'react';
import stSearch  from '../smart-table-preact';
import {debounce} from './helpers' // a debounce helper function

export const SearchInput = stSearch.search(class SearchInput extends React.Component {
  constructor (props) {
    const {stDirective} = props;
    super(props);
    this.onChange = this.onChange.bind(this);
    this.state = {text: ''};
    this.commitChange = debounce(() => {
      stDirective.search(this.state.text);
    }, props.delay || 300)
  }

  onChange (e) {
    const text = e.target.value.trim();
    this.setState({text});
    this.commitChange();
  }

  render () {
    return (
      <label>
        Search Input
        <input type="search"
               placeholder={this.props.placeholder}
               value={this.state.text}
               onInput={this.onChange}/>
      </label>
    );
  }
});

/*
to be used
...
 <SearchInput placeholder="search name and surname" smartTable={t} stSearchScope={['surname', 'name']}/>
...

 */

Filter HOC

This mixin will help you to use the filter directive in your components

Configuration attributes

smartTable
The instance of smart table
stFilter
The pointer to the filtered property
stFilterType
The type of the property (defaults to string)
stFilterOperator
The operator of the filter clause (defaults to "includes")

Example

An example of a filter input component which will trigger a filter query whenever the input value changes

import React from 'react';
import st from './smart-table.js';
import {debounce} from './helpers'; // a debounce function


export const FilterTextInput = st.filter(class FilterInput extends React.Component {
  constructor (props) {
    const {stDirective} = props;
    super(props);
    this.onChange = this.onChange.bind(this);
    this.state = {value: ''};
    this.commitChange = debounce(() => {
      stDirective.filter(this.state.value);
    }, props.delay || 300)
  }

  onChange (e) {
    const value = e.target.value.trim();
    this.setState({value});
    this.commitChange();
  }

  render () {
    const {label} = this.props;
    return (
      <label>
        {label}
        <input placeholder={this.props.placeholder}
               value={this.state.value}
               onInput={this.onChange}/>
      </label>
    );
  }
});

/*
 To be used

 <FilterTextInput label="surname" smartTable={t} stFilter="surname" />
 <FilterTextInput label="name" smartTable={t} stFilter="name" stFilterOperator="is" />

 */

Pagination HOC

This HOC will help you to use the slice directive to build advanced pagination components

Configuration attributes

smartTable
The instance of smart-table

Example

This example provides a basic pagination component displaying the current page and which allows to go the previous or the next page

import React from 'react';
import st from './smart-table.js';

export const Pagination = st.pagination(({stDirective, stState}) => {
  const isPreviousDisabled = !stDirective.isPreviousPageEnabled();
  const isNextDisabled = !stDirective.isNextPageEnabled();
  return <td>
    <div>
      <button disabled={isPreviousDisabled} onClick={stDirective.selectPreviousPage}>
        Previous
      </button>
      <span>Page {stState.page}</span>
      <button disabled={isNextDisabled} onClick={stDirective.selectNextPage}>
        Next
      </button>
    </div>
  </td>
});

/*
 To be used

 <Pagination smartTable={t} />

 */

Loading indicator HOC

This HOC will help you tu use the loading indicator directive.

Configuration attributes

smartTable
The instance of smart-table

Example

This example will change the class name of a loading indicator overlay depending on the current processing state of the component

import React from 'react';
import st from '../smart-table-preact';

export const Overlay = st.loadingIndicator(({stState}) => {
  const {working} = stState;
  return <div id="overlay" className={working ? 'st-working' : ''}>Processing ...</div>;
});

/*
 To be used

 <Overlay smartTable={t} />

 */