Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question about inheritance and atomic design #59

Closed
jlmitch5 opened this issue Jan 8, 2017 · 2 comments
Closed

Question about inheritance and atomic design #59

jlmitch5 opened this issue Jan 8, 2017 · 2 comments

Comments

@jlmitch5
Copy link

jlmitch5 commented Jan 8, 2017

I've been trying to find examples of structuring really large UI applications and came across arc. I feel like the concepts here are very, very cool!

One thing I'm having trouble trying to figure out is if inheritance can fit into the flow. By inheritance, I mean taking a basic atom (or molecule, organism, template... probably not page) and inheriting all of it's properties while adding in more specific ones.

Let's use the example of a Button atom:

Let's say our Button atom can have several properties. Things like "disabled", "innerContent", "hidden", "color".

These are things that all Buttons in our app need, but what if we have we want to have a button with a more detailed spec. For example, we have lists in our app and there are action buttons in each row of the app:

screen shot 2017-01-08 at 2 52 36 pm

These buttons need the same properties as our Button atom, but they also have specific requirements like "the button should be a cricle", "the button should have no color unless the user hovers on it", etc.

So on to the actual questions:
Can we create a RowActionButton atom that inherits from our Button atom?
Since the atom is only useful in our ListRow molecule, can we place it in the folder structure within that molecule's specification?

@diegohaz
Copy link
Owner

diegohaz commented Jan 8, 2017

I would not use inheritance, but composition. Something like this:

import styled from 'styled-components'
import { Button } from 'components'

const StyledButton = styled(Button)`
  border-radius: 50%;
  width: 40px;
  height: 40px;
`

const RowActionButton = (props) => <StyledButton {...props} />

export default RowActionButton

The different SomethingButton's should be molecules.

@jlmitch5
Copy link
Author

jlmitch5 commented Jan 21, 2017

Hey @diegohaz, I just wanted to share some things I've learned since exploring the styled-components more deeply.

First of all, thank you for pointing me in the direction, as I'm loving the explicit, compositional inheritance pattern using styled-components keeps you in. The code you describe in the above gist is how I've implemented most of the components I've tried so far (reworking the main layout and dashboard of the app I work on).

There's one particular case where I had to do things a little differently, and I wanted to share for others who might happen upon this issue.

There are times where you might need to share styles between components, but they can't be composed of a common ancestor. I ran into this when working on our horizontal nav components. Here's a subsection of those:

screen shot 2017-01-21 at 4 54 11 pm

All but one of these are a styled version of the Link component, and link to various sub-routes in the app. The exception is the icon that looks like a book...which links outside of the app to our documentation site. You cannot link outside of your react app to a different url using the react-router's link component, so you can't really do inheritance in a compositional way.

I got around this by using the styled-component's css template tag function to keep the styles that the two different types of components need to share in one place (so you don't have to edit things in two places when things change). I guess you could consider this a "mix-in" inheritance pattern. Anyways, here's what the code looks like:

import {Link} from 'react-router';
import styled, {css} from 'styled-components';

const consistentLinkCSS = css`
  color: ${props => props.theme.interfaceText}
  text-decoration: none;
  border-bottom: 5px solid transparent;
  padding: ${props => props.theme.pad * 2}px ${props => props.theme.pad * 2.25}px;
  &:hover {
    background: ${props => props.theme.navItemBackground};
    border-color: ${props => props.theme.navItemBorder};
  }
`;

// used for styling react-router links
const StyledLink = styled(Link)`
  ${consistentLinkCSS}
  &.active {
    background: ${props => props.theme.navItemBackground};
    border-color: ${props => props.theme.navItemBorder};
  }
`;

// used for styling links out to other websites (i.e. the docs link)
const StyledLinkOut = styled.a`
  ${consistentLinkCSS}
`;

Thank you for you explanation, it definitely pointed me in the right direction! And just as a note, right now, I'm just keeping everything in a components folder in my app, as that seems to be easiest while things are "small", but I'll definitely be exploring the atomic design way of structuring once things start to become too unwieldy.

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

No branches or pull requests

2 participants