<body class="scenery"> <section class="scenery__sky"> <div class="sky [sky--dusk / sky--daytime] [sky--foggy]"> <div class="sky__clouds"></div> <div class="sky__sun"></div> </div> </section> <section class="scenery__ground"></section> <section class="scenery__people"></section> </body>
.scenery
and .sky
. Each of them has its own blocks. Only sky
has modifiers, because, for example, fog, day or sunset are all different characteristics that can be applied to the same element. // Block .scenery { //Elements &__sky { fill: screen; } &__ground { float: bottom; } &__people { float: center; } } //Block .sky { background: dusk; // Elements &__clouds { type: distant; } &__sun { strength: .025; } // Modifiers &--dusk { background: dusk; .sky__clouds { type: distant; } .sky__sun { strength: .025; } } &--daytime { background: daylight; .sky__clouds { type: fluffy; float: center; } .sky__sun { strength: .7; align: center; float: top; } } }
@import '~tools/theme'; :local(.root) { border: 1px solid; font-family: inherit; font-size: 12px; color: inherit; background: none; cursor: pointer; display: inline-block; text-transform: uppercase; letter-spacing: 0; font-weight: 700; outline: none; position: relative; transition: all 0.3s; text-transform: uppercase; padding: 10px 20px; margin: 0; border-radius: 3px; text-align: center; } @mixin button($bg-color, $font-color) { background: $bg-color; color: $font-color; border-color: $font-color; &:focus { border-color: $font-color; background: $bg-color; color: $font-color; } &:hover { color: $font-color; background: lighten($bg-color, 20%); } &:active { background: lighten($bg-color, 30%); top: 2px; } } :local(.primary) { @include button($color-primary, $color-white) } :local(.secondary) { @include button($color-white, $color-primary) }
className
with the addition of :local
will generate unique class names like: .app–components–button–__root — 3vvFf {}
localIdentName
request localIdentName
. Example: css–loader?localIdentName=[path][name]–––[local]–––[hash:base64:5]
to facilitate debugging.className
that will not conflict with any other, even if the same name is used. Very convenient. import React from "react" import styled from "styled-components" // Simple form component const Input = styled.input` background: green ` const FormWrapper = () => <Input placeholder="hola" /> // What this compiles to: <input placeholder="hola" class="dxLjPX">Send</input>
import styled from "styled-components" const Sky = styled.section` ${props => props.dusk && 'background-color: dusk' } ${props => props.day && 'background-color: white' } ${props => props.night && 'background-color: black' } `; // You can use it like so: <Sky dusk /> <Sky day /> <Sky night />
import React from "react"; import classNames from "classnames"; import styles from "./styles"; const Button = (props) => { const { className, children, theme, tag, ...rest } = props; const CustomTag = `${tag}`; return ( <CustomTag { ...rest } className={ classNames(styles.root, theme, className) }> { children } </CustomTag> ); }; Button.theme = { secondary: styles.secondary, primary: styles.primary }; Button.defaultProps = { theme: Button.theme.primary, tag: "button" }; Button.displayName = Button.name; Button.propTypes = { theme: React.PropTypes.string, tag: React.PropTypes.string, className: React.PropTypes.string, children: React.PropTypes.oneOfType([ React.PropTypes.string, React.PropTypes.element, React.PropTypes.arrayOf(React.PropTypes.element) ]) }; export default Button;
import React from "react" import Button from "components/core/button" const = Component = () => <Button theme={ Button.theme.secondary }>Some Button</Button> export default Component
import styled from "styled-components"; import { theme } from "ui"; const { color, font, radius, transition } = theme; export const Button = styled.button` background-color: ${color.ghost}; border: none; appearance: none; user-select: none; border-radius: ${radius}; color: ${color.base} cursor: pointer; display: inline-block; font-family: inherit; font-size: ${font.base}; font-weight: bold; outline: none; position: relative; text-align: center; text-transform: uppercase; transition: transorm ${transition}, opacity ${transition}; white-space: nowrap; width: ${props => props.width ? props.width : "auto"}; &:hover, &:focus { outline: none; } &:hover { color: ${color.silver}; opacity: 0.8; border-bottom: 3px solid rgba(0,0,0,0.2); } &:active { border-bottom: 1px solid rgba(0,0,0,0.2); transform: translateY(2px); opacity: 0.95; } ${props => props.disabled && ` background-color: ${color.ghost}; opacity: ${0.4}; pointer-events: none; cursor: not-allowed; `} ${props => props.primary && ` background-color: ${color.primary}; color: ${color.white}; border-color: ${color.primary}; &:hover, &:active { background-color: ${color.primary}; color: ${color.white}; } `} ${props => props.secondary && ` background-color: ${color.secondary}; color: ${color.white}; border-color: ${color.secondary}; &:hover, &:active { background-color: ${color.secondary}; color: ${color.white}; } `} `;
// Prop passing Shorthands for Styled-components export const borderProps = props => css` ${props.borderBottom && `border-bottom: ${props.borderWidth || "1px"} solid ${color.border}`}; ${props.borderTop && `border-top: ${props.borderWidth || "1px"} solid ${color.border}`}; ${props.borderLeft && `border-left: ${props.borderWidth || "1px"} solid ${color.border}`}; ${props.borderRight && `border-right: ${props.borderWidth || "1px"} solid ${color.border}`}; `; export const marginProps = props => css` ${props.marginBottom && `margin-bottom: ${typeof (props.marginBottom) === "string" ? props.marginBottom : "1em"}`}; ${props.marginTop && `margin-top: ${typeof (props.marginTop) === "string" ? props.marginTop : "1em"}`}; ${props.marginLeft && `margin-left: ${typeof (props.marginLeft) === "string" ? props.marginLeft : "1em"}`}; ${props.marginRight && `margin-right: ${typeof (props.marginRight) === "string" ? props.marginRight : "1em"}`}; ${props.margin && `margin: ${typeof (props.margin) === "string" ? props.margin : "1em"}`}; ${props.marginVertical && ` margin-top: ${typeof (props.marginVertical) === "string" ? props.marginVertical : "1em"} margin-bottom: ${typeof (props.marginVertical) === "string" ? props.marginVertical : "1em"} `}; ${props.marginHorizontal && ` margin-left: ${typeof (props.marginHorizontal) === "string" ? props.marginHorizontal : "1em"} margin-right: ${typeof (props.marginHorizontal) === "string" ? props.marginHorizontal : "1em"} `}; `; // An example of how you can use it with your components const SomeDiv = styled.div` ${borderProps} ${marginProps} ` // This lets you pass all borderProps to the component like so: <SomeDiv borderTop borderBottom borderLeft borderRight marginVertical>
// Mixin like functionality const textInput = props => ` color: ${props.error ? color.white : color.base}; background-color: ${props.error ? color.alert : color.white}; `; export const Input = styled.input` ${textInput} `; export const Textarea = styled.textarea` ${textInput}; height: ${props => props.height ? props.height : '130px'} resize: none; overflow: auto; `;
import styled from "styled-components"; import { theme, borderProps, sizeProps, backgroundColorProps, marginProps } from "ui"; const { color, font, topbar, gutter } = theme; export const Panel = styled.article` ${marginProps} padding: 1em; background: white; color: ${color.black}; font-size: ${font.base}; font-weight: 300; ${props => !props.noborder && `border: 1px solid ${color.border}`}; width: ${props => props.width ? props.width : "100%"}; ${props => borderProps(props)} transition: transform 300ms ease-in-out, box-shadow 300ms ease-in-out, margin 300ms ease-in-out; box-shadow: 0 3px 3px rgba(0,0,0,0.1); ${props => props.dark && ` color: ${color.white}; background-color: ${color.black}; `} &:hover { transform: translateY(-5px); box-shadow: 0 6px 3px rgba(0,0,0,0.1); } `; export const ScrollView = styled.section` overflow: hidden; font-family: ${font.family}; -webkit-overflow-scrolling: touch; overflow-y: auto; ${props => props.horizontal && ` white-space: nowrap; overflow-x: auto; overflow-y: hidden; ` } ${props => sizeProps(props)} `; export const MainContent = styled(ScrollView)` position: absolute; top: ${props => props.topbar ? topbar.height : 0}; right: 0; left: 0; bottom: 0; font-size: ${font.base}; padding: ${gutter} 3em; ${props => props.bg && ` background-color: ${props.bg}; `} `; export const Slide = styled.section` ${backgroundColorProps} font-weight: 400; flex: 1; height: ${props => props.height ? props.height : "100%"}; width: ${props => props.width ? props.width : "100%"}; justify-content: center; flex-direction: column; align-items: center; text-align: center; display: flex; font-size: 3em; color: ${color.white}; `; export const App = styled.div` *, & { box-sizing: border-box; } `;
<ScrollView />
component receives the width and height properties as well as the horizontal property for the scroll bar that appears at the bottom. import styled, { css } from "styled-components"; import { borderProps, marginProps, backgroundColorProps, paddingProps, alignmentProps, positioningProps, sizeProps, spacingProps, theme } from "ui"; const { screenSizes } = theme; export const overlay = ` position: fixed; top: 0; left: 0; right: 0; bottom: 0; display: flex; align-items: center; justify-content: center; background: rgba(0,0,0,0.5); `; // You can use this like ${media.phone`width: 100%`} export const media = Object.keys(screenSizes).reduce((accumulator, label) => { const acc = accumulator; acc[label] = (...args) => css` @media (max-width: ${screenSizes[label]}em) { ${css(...args)} } `; return acc; }, {}); // Spacing export const Padder = styled.section` padding: ${props => props.amount ? props.amount : "2em"}; `; export const Spacer = styled.div` ${spacingProps} `; // Alignment export const Center = styled.div` ${borderProps} ${marginProps} ${backgroundColorProps} ${paddingProps} ${alignmentProps} ${positioningProps} ${sizeProps} text-align: center; margin: 0 auto; `; // Positioning export const Relative = styled.div` ${props => borderProps(props)}; position: relative; `; export const Absolute = styled.div` ${props => marginProps(props)}; ${props => alignmentProps(props)}; ${props => borderProps(props)}; position: absolute; ${props => props.right && `right: ${props.padded ? "1em" : "0"}; `} ${props => props.left && `left: ${props.padded ? "1em" : "0"}`}; ${props => props.top && `top: ${props.padded ? "1em" : "0"}`}; ${props => props.bottom && `bottom: ${props.padded ? "1em" : "0"}`}; `; // Patterns export const Collapsable = styled.section` opacity: 1; display: flex; flex-direction: column; ${props => props.animate && ` transition: transform 300ms linear, opacity 300ms ease-in, width 200ms ease-in, max-height 200ms ease-in 200ms; max-height: 9999px; transform: scale(1); transform-origin: 100% 100%; ${props.collapsed && ` transform: scale(0); transition: transform 300ms ease-out, opacity 300ms ease-out, width 300ms ease-out 600ms; `} `} ${props => props.collapsed && ` opacity: 0; max-height: 0; `} `; export const Ellipsis = styled.div` max-width: ${props => props.maxWidth ? props.maxWidth : "100%"}; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; `; export const Circle = styled.span` ${backgroundColorProps} display: inline-block; border-radius: 50%; padding: ${props => props.padding || '10px'}; `; export const Hidden = styled.div` display: none; `;
export const theme = { color: { primary: "#47C51D", secondary: '#53C1DE', white: "#FFF", black: "#222", border: "rgba(0,0,0,0.1)", base: "rgba(0,0,0,0.4)", alert: '#FF4258', success: 'mediumseagreen', info: '#4C98E6', link: '#41bbe1' }, icon: { color: "gray", size: "15px" }, font: { family: ` -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'`, base: '13px', small: '11px', xsmall: '9px', large: '20px', xlarge: '30px', xxlarge: '50px', }, headings: { family: 'Helvetica Neue', }, gutter: '2em', transition: '300ms ease-in-out' }; export default theme;
className
(this is done without your participation).aria-label
or using className
.Source: https://habr.com/ru/post/319956/
All Articles