Skip to content

Instantly share code, notes, and snippets.

@streamich
Last active April 25, 2018 12:07
Show Gist options
  • Save streamich/1ef6c3a8c3e1d94b41655fd7dfb3a85b to your computer and use it in GitHub Desktop.
Save streamich/1ef6c3a8c3e1d94b41655fd7dfb3a85b to your computer and use it in GitHub Desktop.

State selector interface brainstorming for nano-css.

Iteration 1:

const styles = block({
  ':scope': {
    bgc: '#ed2651',
    bd: 0,
    bdrad: '2px',
    bxz: 'border-box',
    col: 'white',
    h: '24px',
    lh: '24px',
    ov: 'hidden',
    pad: '0 16px',
  },
  ':scope[state|inverse]': {
    bgc: 'white',
    col: '#2e184a',
  },
  ':scope[state|size=small]': {
    h: '16px',
    lh: '16px'
    pad: '0px 8px',
  },
  '.icon': {
    w: '16px',
    mart: '8px',
    ov: 'hidden',
    height: '16px',
  },
  '.icon[state|animate]': {
    animation: '3s ease-in 1s icon-animation',
  },
});

const Button = ({size, inverse, icon, children}) => {
  const style = objstr({
    [styles]: true,
    [styles.inverse()]: inverse,
    [styles.size(size)]: true
  });

  return (
    <button class={style}>
      {icon && <span class={styles.icon}>{icon}</span>}
      {children}
    </button>
  );
}
@streamich
Copy link
Author

streamich commented Apr 25, 2018

Iteration 2 (implicit scope):

const styles = block({
  bgc: '#ed2651',
  bd: 0,
  bdrad: '2px',
  bxz: 'border-box',
  col: 'white',
  h: '24px',
  lh: '24px',
  ov: 'hidden',
  pad: '0 16px',
  '[state|inverse]': {
    bgc: 'white',
    col: '#2e184a',
  },
  '[state|size=small]': {
    h: '16px',
    lh: '16px'
    pad: '0px 8px',
  },
  icon: {
    w: '16px',
    mart: '8px',
    ov: 'hidden',
    height: '16px',
    '[state|animate]': {
      animation: '3s ease-in 1s icon-animation',
    },
  },
});

const Button = ({size, inverse, icon, children}) => {
  const style = objstr({
    [styles]: true,
    [styles.inverse()]: inverse,
    [styles.size(size)]: true
  });

  return (
    <button class={style}>
      {icon && <span class={styles.icon}>{icon}</span>}
      {children}
    </button>
  );
}

@streamich
Copy link
Author

streamich commented Apr 25, 2018

Iteration 3 (use props):

const styles = block({
  bgc: '#ed2651',
  bd: 0,
  bdrad: '2px',
  bxz: 'border-box',
  col: 'white',
  h: '24px',
  lh: '24px',
  ov: 'hidden',
  pad: '0 16px',
  '[state|inverse]': {
    bgc: 'white',
    col: '#2e184a',
  },
  '[state|size=small]': {
    h: '16px',
    lh: '16px'
    pad: '0px 8px',
  },
  icon: {
    w: '16px',
    mart: '8px',
    ov: 'hidden',
    height: '16px',
    '[state|animate]': {
      animation: '3s ease-in 1s icon-animation',
    },
  },
});

const Button = (props) => {
  const style = objstr(props);

  return (
    <button class={style}>
      {icon && <span class={styles.icon}>{icon}</span>}
      {children}
    </button>
  );
}

@streamich
Copy link
Author

Iteration 4 (state as AST):

const styles = block({
  bgc: '#ed2651',
  bd: 0,
  bdrad: '2px',
  bxz: 'border-box',
  col: 'white',
  h: '24px',
  lh: '24px',
  ov: 'hidden',
  pad: '0 16px',
  state: {
    inverse: {
      bgc: 'white',
      col: '#2e184a',
    },
    size: {
      value: 'small',
      h: '16px',
      lh: '16px'
      pad: '0px 8px',
    },
  },
  icon: {
    w: '16px',
    mart: '8px',
    ov: 'hidden',
    height: '16px',
    state: {
      animate: {
        animation: '3s ease-in 1s icon-animation',
      },
    },
  },
});

const Button = (props) => {
  const style = objstr(props);

  return (
    <button class={style}>
      {icon && <span class={styles.icon}>{icon}</span>}
      {children}
    </button>
  );
}

@streamich
Copy link
Author

streamich commented Apr 25, 2018

Iteration 5 (no objstr):

const styles = block({
  bgc: '#ed2651',
  bd: 0,
  bdrad: '2px',
  bxz: 'border-box',
  col: 'white',
  h: '24px',
  lh: '24px',
  ov: 'hidden',
  pad: '0 16px',
  state: {
    inverse: {
      bgc: 'white',
      col: '#2e184a',
    },
    size: {
      value: 'small',
      h: '16px',
      lh: '16px'
      pad: '0px 8px',
    },
  },
  icon: {
    w: '16px',
    mart: '8px',
    ov: 'hidden',
    height: '16px',
    state: {
      animate: {
        animation: '3s ease-in 1s icon-animation',
      },
    },
  },
});

const Button = (props) =>
  <button class={styles(props)}>
    {icon && <span class={styles.icon}>{icon}</span>}
    {children}
  </button>;

@streamich
Copy link
Author

streamich commented Apr 25, 2018

Iteration 6 (prefix with $):

const styles = block({
  bgc: '#ed2651',
  bd: 0,
  bdrad: '2px',
  bxz: 'border-box',
  col: 'white',
  h: '24px',
  lh: '24px',
  ov: 'hidden',
  pad: '0 16px',
  $state: {
    inverse: {
      bgc: 'white',
      col: '#2e184a',
    },
    size: {
      $value: 'small',
      h: '16px',
      lh: '16px'
      pad: '0px 8px',
    },
  },
  icon: {
    w: '16px',
    mart: '8px',
    ov: 'hidden',
    height: '16px',
    $state: {
      animate: {
        animation: '3s ease-in 1s icon-animation',
      },
    },
  },
});

const Button = (props) =>
  <button class={styles(props)}>
    {icon && <span class={styles.icon}>{icon}</span>}
    {children}
  </button>;

@streamich
Copy link
Author

streamich commented Apr 25, 2018

Iteration 7 (use $ also for generated class names):

const styles = block({
  bgc: '#ed2651',
  bd: 0,
  bdrad: '2px',
  bxz: 'border-box',
  col: 'white',
  h: '24px',
  lh: '24px',
  ov: 'hidden',
  pad: '0 16px',
  $state: {
    inverse: {
      bgc: 'white',
      col: '#2e184a',
    },
    size: {
      $value: 'small',
      h: '16px',
      lh: '16px'
      pad: '0px 8px',
    },
  },
  $icon: {
    w: '16px',
    mart: '8px',
    ov: 'hidden',
    height: '16px',
    $state: {
      animate: {
        animation: '3s ease-in 1s icon-animation',
      },
    },
  },
});

const Button = (props) =>
  <button class={styles(props)}>
    {icon && <span class={styles.icon}>{icon}</span>}
    {children}
  </button>;

@streamich
Copy link
Author

streamich commented Apr 25, 2018

Iteration 8:

const styles = block({
  bgc: '#ed2651',
  bd: 0,
  bdrad: '2px',
  bxz: 'border-box',
  col: 'white',
  h: '24px',
  lh: '24px',
  ov: 'hidden',
  pad: '0 16px',
  '&[state|inverse]': {
    bgc: 'white',
    col: '#2e184a',
  },
  '&[state|size=small]': {
    h: '16px',
    lh: '16px'
    pad: '0px 8px',
  },
  $icon: {
    w: '16px',
    mart: '8px',
    ov: 'hidden',
    height: '16px',
    '&[state|animate]': {
      animation: '3s ease-in 1s icon-animation',
    },
  },
}, 'Button');

const Button = (props) =>
  <button class={styles(props)}>
    {icon && <span class={styles.icon}>{icon}</span>}
    {children}
  </button>;

@streamich
Copy link
Author

streamich commented Apr 25, 2018

Compiles to:

.Button {
  background-color: #ed2651;
  border: 0;
  border-radius: 2px;
  box-sizing: border-box;
  color: white;
  height: 24px;
  line-height: 24px;
  overflow: hidden;
  padding: 0 16px;
}

.Button--inverse {
  background-color: white;
  color: #2e184a;
}

.Button--size-small {
  height: 16px;
  line-height: 16px;
  padding: 0px 8px;
}

.Button--animate .Button__icon {
  animation: 3s ease-in 1s icon-animation;
}

.Button__icon {
  width: 16px;
  margin-right: 8px;
  overflow: hidden;
  height: 16px;
}

@streamich
Copy link
Author

Iteration 9 (helper function):

const styles = block({
  bgc: '#ed2651',
  bd: 0,
  bdrad: '2px',
  bxz: 'border-box',
  col: 'white',
  h: '24px',
  lh: '24px',
  ov: 'hidden',
  pad: '0 16px',
  [state('inverse')]: {
    bgc: 'white',
    col: '#2e184a',
  },
  [state('size', 'small')]: {
    h: '16px',
    lh: '16px'
    pad: '0px 8px',
  },
  $icon: {
    w: '16px',
    mart: '8px',
    ov: 'hidden',
    height: '16px',
    [state('animate')]: {
      animation: '3s ease-in 1s icon-animation',
    },
  },
}, 'Button');

const Button = (props) =>
  <button class={styles(props)}>
    {icon && <span class={styles.icon}>{icon}</span>}
    {children}
  </button>;

@streamich
Copy link
Author

Iteration 10 (spread):

const styles = block({
  bgc: '#ed2651',
  bd: 0,
  bdrad: '2px',
  bxz: 'border-box',
  col: 'white',
  h: '24px',
  lh: '24px',
  ov: 'hidden',
  pad: '0 16px',
  ...state('inverse', {
    bgc: 'white',
    col: '#2e184a',
  }),
  ...state('size', 'small', {
    h: '16px',
    lh: '16px'
    pad: '0px 8px',
  }),
  $icon: {
    w: '16px',
    mart: '8px',
    ov: 'hidden',
    height: '16px',
    ...state('animate', {
      animation: '3s ease-in 1s icon-animation',
    }),
  },
}, 'Button');

const Button = (props) =>
  <button class={styles(props)}>
    {icon && <span class={styles.icon}>{icon}</span>}
    {children}
  </button>;

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