Skip to content

Instantly share code, notes, and snippets.

@shlomitc
Last active April 2, 2019 14:19
Show Gist options
  • Save shlomitc/86ca1368bee27fe900f4c0ae0599afb3 to your computer and use it in GitHub Desktop.
Save shlomitc/86ca1368bee27fe900f4c0ae0599afb3 to your computer and use it in GitHub Desktop.
Components APIs - Composition vs. Wrapping

Components APIs - Composition vs. Wrapping

The Task:

Create a preview component for social links:

image

The component should be created on top of existing components in the library. Consider the following components:

  1. Text - represnets text in different combinations
  2. ImageViewer - an image picker with additional info

The issues

  1. What APIs should the component have in order to make it consistent, easy to use and to test
  2. The ImageViewer component has rounded corners and fixed size. Should be 100% width/height and with squared corners. This is a requirement only for SocialPreview and not for ImageViewer.

The Approaches:

Approach 1 - CSS composition

const SocialPreview = ({children}) => (
  <div className={styles.socialPreviewComposition}>
    {children}
  </div>
);


const App = () => (
  <SocialPreview>
    <ImageViewer imageUrl="http://wix.com/image.png”/>
    <Text>Preview Url</Text>
    <Text>Title</Text>
    <Text>Description</Text>  
  </SocialPreview>
);

Pros:

  1. Straightforward API
  2. Easy to test each part with it’s own drivers

Cons:

  1. Prone to composition mistakes (since not closed in the component)
  2. Harder to document

Magic:

  1. ImageViewer needs to be configured no to have borders, so the css can apply styles on it with css, or it can be added to the ImageViewer directly

Approach 2 - pass imageViewerProps and propagte to ImageViewer

<SocialPreview
  previewUrl="www.site-name.com"
  title="Site Name | a title of you site"
  description="A short description for a site"
  imageViewerProps={{
    imageUrl: 'https://wix.com/image.png’,
  }}
/>

Pros:

  1. Straightforward
  2. Protected from making mistakes

Cons:

  1. Harder to test the image component
  2. Couples the component directly to ImageViewer, so refactors are harder. Internal implementation becomes public.

Approach 3 - pass <ImageViewer/> as a prop

<SocialPreview
  previewUrl="www.site-name.com"
  title="Site Name | a title of you site"
  description="A short description for a site"
  media={
    <ImageViewer imageUrl="https://wix.com/image.png"/> 
  }
/>

Pros:

  1. 1/2 Straightforward
  2. 1/2 Protected from making mistakes
  3. Testing is easier since data-hook can be applied directly

Cons:

  1. Harder to test the image component

Magic:

  1. Css can be done either internally, but it’s a wild guess, or it needs to be supplied to the ImageViewer

Pros and Cons

Criteria Approach 1 Approach 2 Approach 3
Straightforward API V X X
Test drivers simplicity V X V
Mistake-free (wrong configuration) X V X
Easy to document V V X
Configuring ImageViewer correctly X V X
@shlomitc
Copy link
Author

shlomitc commented Apr 2, 2019

this is like approach 1 - only with props and not just children.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment