0

Is it possible to define a component interface library, and have the actual implementation library be linked at runtime or if not possible compile time. I am looking for a solution that relies on inversion of control and not clutter conditions (switch / if) everywhere.

More or Less:

interface ButtonProps {
  children: string
}
const Button: (props: ButtonProps) => ReactElement = () => {
  throw new Error('not implemented')
}

const Components = {
  Button,
}

const FooButton: typeof Button = p => <button>{p.children} Foo</button>
const BarButton: typeof Button = p => <input type="button" value={p.children + ' Bar'} />

function App() {
  return (
    <div className="App">
        <Components.Button>Click Here</Components.Button>
        <Button>Click Here</Button>
    </div>
  );
}

Components.Button = FooButton
Button = BarButton

Instead of:

function Button(p: ButtonProps) {
  switch (implementation) {
    case 'Foo': return <button>{p.children}</button>
    case 'Bar': return <input type="button" value={p.children} />
  }
  throw new Error('not implemented')
}

I am not trying to have multiple Themes. What I want is to be able to switch out the implementation of the UI components. For instance, a MUI based implementation or another HTML based Library or maybe having a device / environment dependant implementation, e.g. capacitorjs or React Native for a Native App, whatever.

The first example above seems to work, but I do not know if there are any downsides to that solution. Or if there are better approaches. Biggest downside might be possibly stale references in other files. Also I do not want to end up with something over-engineered which nobody understands or has more drawbacks than advantages.

Philippe
  • 51
  • 5

0 Answers0