Wednesday, July 28, 2021

WiP: showing state combinations of components

This is a work in progress, and is probably the wrong idea in general (see earlier and later posts) but I'm kind of proud of the concept...

One thing I am adding to my team is the idea of making things visible, so that dev testing and QA is easier, seeing things work in context. (For example I made a "formik playground" page in storybook so we could see our components work in formik context, still work out of that context, and then how formik "regular" fields would work so we could compare behaviors etc)

Related to that, my team has realized we sort of painted outselves in a corner in terms of not thinking about different possible states of components (error, disabled, selected, etc) function together. Most of these are "boolean" properties so I thought a simple grid could let us see all the two-fold combinations, how the states play together:

The end result looked like:



And the code (not quite perfected, especially from the typescripting complaints side:)


import React from 'react';
import PropTestingProps from './prop-testing.props';
import PropTestingComponent from './prop-testing.style';
import { Button } from '../Button/button.component';

import { Checkbox } from '../Checkbox/checkbox.component';
import { Radio } from '../Radio/radio.component';
import styled from 'styled-components';

const Table = styled.table`
  th {
    font-weight: bold;
  }
  th, td {
    padding: 8px;
    font-family: sans-serif;
  }
`;

interface ComponentPropMatrixProps {
  label: string,
  permutations: string[],
  render: React.FC
}
interface ComponentPropRowProps extends ComponentPropMatrixProps {
  rowEntry: string,
  permutations: string[],
  render: React.FC
}

const ComponentPropRow = (props: ComponentPropRowProps) => {
  const {permutations, rowEntry, render} = props;
  
  return (<tr>{permutations.map((colEntry: string)=>{
    const componentProps = {[colEntry] : true, [rowEntry]: true };
    return (<td key={colEntry}>
      {render({componentProps,label:`${rowEntry}`})}
        </td>);
  })}</tr>);
}

const ComponentPropMatrix = (props: ComponentPropMatrixProps) => {
  const {permutations, render, label} = props;
  return <>
    <h3>{label}</h3>
    <Table>
    <thead>
      <tr>
        {permutations.map(x => <th><b>{x} +</b></th>)}
      </tr>
    </thead>
    <tbody>
      {permutations.map((x,i) => {return <ComponentPropRow key={x} 
          render={render} permutations={permutations} rowEntry={x}/>})}
    </tbody>
    </Table>
    </>

}
// idle, checked, error, disabled

const PropTesting = (props: PropTestingProps) => {
  return <PropTestingComponent>
    <ComponentPropMatrix label="Checkbox" 
      permutations={['idle', 'checked','error','disabled']} 
      render={({componentProps,label})=><Checkbox {...componentProps} 
        label={label} />} />

    <ComponentPropMatrix label="Radio" 
       permutations={['idle', 'checked','error','disabled']} 
      render={({componentProps,label})=><Radio {...componentProps} 
         id={`${JSON.stringify(componentProps)}!`} label={label} />} />


    <ComponentPropMatrix label="Button sm primary" 
      permutations={[`'idle'`,'disabled']} 
      render={({componentProps,label})=><Button size="sm" 
      buttonType="primary" {...componentProps}>{label}</Button>} />
    <ComponentPropMatrix label="Button md tertiary" 
      permutations={[`'idle'`,'disabled']} 
      render={({componentProps,label})=><Button size="md" 
      buttonType="tertiary" {...componentProps}>{label}</Button>} />
    <ComponentPropMatrix label="Button lg oval" 
      permutations={[`'idle'`,'disabled']} 
      render={({componentProps,label})=><Button size="lg"  
      shape="oval" {...componentProps}>{label}</Button>} />

  </PropTestingComponent>;
};

export default PropTesting;

No comments:

Post a Comment