Skip to content

Instantly share code, notes, and snippets.

@ilyalesik
Last active May 11, 2019 19:11
Show Gist options
  • Select an option

  • Save ilyalesik/53a171b49203d666f92e40bb68345e3c to your computer and use it in GitHub Desktop.

Select an option

Save ilyalesik/53a171b49203d666f92e40bb68345e3c to your computer and use it in GitHub Desktop.
Reshadow syntax propsal
import React from "react";
import styled from "reshadow";
const css = styled`
button {
width: 250px;
}
span[size='l'] {
text-transform: uppercase;
}
`;
const CommonButton = ({children, ...props}) => <button {...props}>
<span>{children}</span>
</button>;
export default css(CommonButton);
@ilyalesik
Copy link
Author

А писать use:size={size} принципиально? Я в своем примере пытаюсь сматчится на проп size, который можно пробросить в CommonButton.

@lttb
Copy link

lttb commented May 11, 2019

да, важно по нескольким причинам. давай рассмотрим на таком примере:

import React from "react";
import styled, {use} from "reshadow";

const CommonButton = ({children, size, ...props}) => styled`
    button[use|size='l'] {
       text-transform: uppercase;  
    }

    button {
      width: 250px;
    }
`(<button {...use({size})} {...props}>
    <span>{children}</span>
</button>);

export default CommonButton;

с таким интерфейсом решается сразу несколько задач:

  1. by design интуитивно сохраняется контроль над пропсами. в каком смысле:
  • добавили в интерфейс пропсу size
  • если ее не "дестракчерить" и оставить props как есть, то эта пропса в данном примере также попадет на элемент button при спреде пропсов
  • если же ее дестракчерить, но нигде не использовать, тогда появляется неиспользуемая переменная, о которой необходимо заботиться, понимать, что это нужно для блэклиста и так далее, что затрудняет поддержку

применяя "модификатор" size к определенному элементу, мы явно определяем:

  • на каком элементе этот модификатор применим
  • как именно этот модификатор используется
  • можем использовать на разных элементах
  • можем избежать каскадности, явно определяя элементы и их модификаторы, а не делая каскады относительно рутового компонента
  1. также явно расширяется и внешний интерфейс компонента (мы выносим size во внешний интерфейс, чтобы сматчиться на него на рутовом элементе, например)

  2. решадоу - это в первую очередь не про компоненты, а про markup + стили. то есть грубо говоря если автоматически определять пропсы компонента и давать на них сматчиться, то необходимо тогда на уровне статического анализа понять, где идет определение компонента, как можно использовать его пропсы и прочее, что не тривиально (компоненты бывают классами, функциями, пропсы их могут по-разному использоваться, вызываться и прочее), может вести к ошибкам, и уже не настолько абстрактно от конкретной имплементации фреймворка (везде компоненты и их пропсы определяются по-разному)

поэтому пока что кажется правильнее оставить ответственность по поводу стилизации относительно пропсов на стороне самого пользователя

но теоретически можно рассмотреть что-нибудь типа такого:

import React from "react";
import styled from "reshadow";

const CommonButton = ({children, size, ...props}) => styled.use({size})`
    :root[size='l'] {
       text-transform: uppercase;  
    }

    button {
      width: 250px;
    }
`(<button {...props}>
    <span>{children}</span>
</button>);

export default CommonButton;

и решадоу может автоматически определять рутовый элемент, чтобы навесить на него нужные классы (что он и так делает для инлайна стилей с css-custom-properties)

это выглядит сахаром (и то не факт, мне лично профит не очень понятен, зато появляется усложнение в виде дополнительного знания о том, как атрибуты работают с :root и пр), появляется несколько способов сделать одно и то же (модификаторы на root и модификаторы, проставленные на корневой элемент button, например), но можно подумать в эту сторону

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