WIP: Tailwind 유틸리티 우선 유사 구문을 사용하는 스타일이 지정된 구성 요소
그러나 styled-components와 함께 TailWind를 사용하는 방법을 살펴보았을 때 다음과 같은 공포를 느꼈습니다.
It requires you to set up post-css (with all that extra re-render time when developing and config tweaking)
내가 이루고 싶은 것
styled-component를 작성할 때 다음과 같은 구문과 같이 Tailwind를 구문 분석할 수 있는 함수가 필요합니다.
parseUtilsString('bg-blue fc-blue-lighten p-large mt-xl')
이는 다음으로 번역됩니다.
background-color: {defined theme blue};
font-color: {defined theme blue, but two increments lighter};
padding: {defined theme large units};
margin-top: {defined theme extra large units};
margin-bottom: {defined theme extra large units};
스타일 구성 요소에 추가 CSS를 추가하고 테마 변수를 사용하는 옵션도 있었으면 합니다.
소개: tiny-util-first-like-tailwind-sort-of-setup
(이 설정이 완성되면 아마 더 나은 이름을 생각해 낼 것입니다)
설정
이는 매우 간단합니다. 테마 변수를 정의하고
themeParser
또는/및 theme
를 구성 요소로 가져와서 사용합니다.styled-components에서 themeProvider를 사용할 수 있지만 작성하는 것을 알고 있습니다.
font-size: ${props => props.theme.fs.large}
생각보다 길고 번거롭다.
font-size: ${theme.fs.large}
(그래, 나는 내 캐릭터에 대해 게으르거나 싸다)
용법
그렇다면 어떻게 이 새를 날게 할 수 있을까요? 물어. 스니펫은 1000자 이상이므로 다음과 같이 합니다.
import React from 'react'
import styled from 'styled-components';
import {themeParse} from '../Styles/theme'
const HeaderStyle = styled.header`
${themeParse('p-l ta-c')}
font-weight: bold;
`;
const TitleStyle = styled.div`
${themeParse('bg-primary-darkest fs-xl ff-primary fc-white')}
span{
${themeParse('fs-s ff-secondary d-b')}
transform-origin: bottom left;
transform: rotate(-10deg) translateY(4em);
}
`;
export default function Header() {
return (
<HeaderStyle>
<TitleStyle>
<span>Welcom to</span>
tiny-util-first-like-tailwind-sort-of-setup
</TitleStyle>
</HeaderStyle>
)
}
이것은 이와 같은 것으로 렌더링됩니다
사용 방법
themeStyles
의 속성을 수정 및/또는 추가합니다(아마도 모든 유틸리티에 대해 짧은 이름과 같은 부트스트랩 대신 전체 이름을 선호할 것입니다. 결국 text-center
가 ta-c
보다 더 설명적입니다.) import { lighten, darken } from 'polished';
const units = {
xs: 5,
s: 10,
m: 15,
l: 30,
xl: 50,
};
const fonts = {
primary: 'Open Sans',
secondary: 'Cursive',
};
const fontSizes = {
xs: '.85rem',
s: '1rem',
m: '1.2rem',
l: '1.5rem',
xl: '2rem',
};
const colors = {
primary: _setColorMap('#80C565'),
secondary: _setColorMap('#002B55'),
white: _setColorMap('#ffffff'),
};
const theme = {
unit: units,
color: colors,
fontSize: fontSizes,
font: fonts,
};
// Exported for use of independent values
export default theme;
const displays = {
b: 'block',
i: 'inline',
ib: 'inline-block',
f: 'flex',
if: 'inline-flext',
g: 'grid',
};
const textAligns = {
c: 'center',
l: 'left',
r: 'right',
j: 'justify',
};
const themeStyles = {
fc: _renderVariationStyles('color', colors),
ff: _renderStyleSeries('font-family', fonts, false),
fs: _renderStyleSeries('font-size', fontSizes, false),
bg: _renderVariationStyles('background-color', colors, false),
br: _renderStyleSeries('border-radius', units),
p: _renderStyleSeries('padding', units),
py: _renderStyleSeries(['padding-top', 'padding-bottom'], units),
px: _renderStyleSeries(['padding-left', 'padding-right'], units),
m: _renderStyleSeries('margin', units),
my: _renderStyleSeries(['margin-top', 'margin-bottom'], units),
mx: _renderStyleSeries(['margin-left', 'margin-right'], units),
d: _renderStyleSeries('display', displays, false),
ta: _renderStyleSeries('text-align', textAligns, false),
};
/**
* Parser function for tailwind like syntax
*
* @param {String} atomicString A set of tailwind parameters as a string
*/
function themeParse(atomicString) {
var output = atomicString.split(' ').map((classString) => {
const [first, second, third] = classString.split('-');
// Handle "flat" colors
if (themeStyles[first][second].hasOwnProperty('base') && !third) {
return themeStyles[first][second]['base'];
}
return third
? themeStyles[first][second][third]
: themeStyles[first][second];
});
return output;
}
// Exported for use in components
export { themeParse };
/**
* Renders the styles for a property
*
* @param {Array} styles
* @param {Array} units
* @param {Boolean} isPixleValue
*/
function _renderStyleSeries(styles, units, isPixleValue = true) {
// Let us use either a string value or an array
if (!Array.isArray(styles)) styles = [styles];
let styleSerie = {};
let suffix = isPixleValue ? 'px' : '';
for (const unit in units) {
styleSerie[unit] = ``;
styles.forEach((style) => {
styleSerie[unit] += `${style}: ${units[unit]}${suffix};`;
});
}
return styleSerie;
}
/**
* Renders deep nested values as e.g. 'colors'
*
* @param {Array} styles
* @param {Array} units
*/
function _renderVariationStyles(styles, units) {
// Let us use either a string value or an array
if (!Array.isArray(styles)) styles = [styles];
let styleSerie = {};
for (const unit in units) {
styleSerie[unit] = {};
for (const subUnit in units[unit]) {
if (subUnit === 'toString') continue;
styleSerie[unit][subUnit] = ``;
styles.forEach((style) => {
styleSerie[unit][subUnit] += `${style}: ${units[unit][subUnit]};`;
});
}
}
return styleSerie;
}
/**
* Render a color in different variations; light, lighter, lightest and dark, darker, darkest
* Either just pass a mainColor or a set of preferred values
*
* @param {String} mainColor a color hex value for the standard color
* @param {String} dark
* @param {String} darker
* @param {String} darkest
* @param {String} light
* @param {String} lighter
* @param {String} lightest
*/
function _setColorMap(
mainColor,
dark,
darker,
darkest,
light,
lighter,
lightest
) {
if (!mainColor) throw Error('Main color must be provided');
return {
toString: () => mainColor,
base: mainColor,
dark: dark || darken(0.1, mainColor),
darker: darker || darken(0.2, mainColor),
darkest: darkest || darken(0.4, mainColor),
light: light || lighten(0.1, mainColor),
lighter: lighter || lighten(0.2, mainColor),
lightest: lightest || lighten(0.4, mainColor),
};
}
엔딩 노트
그래서 이것은 제가 생각한 것이지만 성능과 확장에 대해 많이 생각하지 않았습니다.
제안이나 의견이 있는 경우(내가 방금 바퀴를 재발명했습니까, 아니면 작동하는 바퀴를 부술 수 있었습니까?) - 낯선 사람처럼 굴지 마십시오! 코멘트를 추가하다. :)
Reference
이 문제에 관하여(WIP: Tailwind 유틸리티 우선 유사 구문을 사용하는 스타일이 지정된 구성 요소), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/jnystromdesign/wip-styled-components-with-tailwind-utility-first-like-syntax-4eed텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)