npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

already-styled-components

v3.1.1

Published

React UI components styled with styled-components.

Downloads

35

Readme

Already styled-components

React UI components styled with ... styled-components. Depends on polished for color shades and on react-transition-group for Navbar transitions. Also contains some inline SVG from fontawesome.

Install

npm i already-styled-components styled-components

(assuming you already have installed react and react-dom)

Available components

Also includes some minor smooth scrolling and animation utilities.

Components

1. Grid

A grid layout implemented with flexbox. The implementation is from Philip Walton's "solved by flexbox" repo. What he describes as Grid is a Row component here and a Grid Cell is a Column. In short, Container component is not really important just a div, only Row and Column are "special". Each Column must be inside a Row. The Columns are responsive by passing props similar to Bootstrap (xs, sm, md, ...) but work the other way around. For example when you specify the extra large (xl) prop this applies to all lower breakpoints. Except of extra small (xs) where it takes the whole row by default. If you don't pass a responsive prop all Columns take the same space inside a Row. See the Column prop table for more details.

Example (holy grail layout)
// A holy grail layout.
import React from "react";
import { createGlobalStyle } from "styled-components";
import { Container, Row, Column } from "already-styled-components";

const GlobalStyle = createGlobalStyle`
  body {
    margin: 0;
  }
`;

export default () => (
  <>
    <GlobalStyle />
    <Container fluid ta="center">
      <Row bc="#eee" h="15vh">
        <Column>Header</Column>
      </Row>
      <Row h="70vh">
        <Column bc="#ddd">Left sidebar</Column>
        <Column bc="#bbb" lg="50%">
          Content
        </Column>
        <Column bc="#aaa">Right sidebar</Column>
      </Row>
      <Row bc="#999" h="15vh">
        <Column>Footer</Column>
      </Row>
    </Container>
  </>
);

i) Container props

✨ Be careful of overflows if you use the width property alongside the padding property (or border). You may want to use the border-box value for the box-sizing property to avoid surprises.

| name | extra info | type | default | | --------- | ----------------------------------------------------------------- | ------ | ------- | | fluid | width: 80% or 100% (fluid prop wins over width prop) | bool | false | | w | width | string | "80%" | | h | height | string | null | | m | margin | string | "auto" | | p | padding | string | null | | ta | text-align | string | null | | c | color | string | null | | bc | background-color | string | null |

ii) Row props

| name | extra info | type | default | | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------- | | gutters | Changes the margin for the Row component and the padding for the immediate child Column components. It's visible if you add a div with a background color inside the Column. | bool | false | | gutterSize | The amount of margin for the Row and padding for the Column children | string | "1em" | | w | width | string | null | | h | height | string | null | | m | margin. If you set gutters={true} this prop will be ignored | string | "0" | | p | padding | string | "0" | | c | color | string | null | | bc | background-color | string | null | | ai | align-items | string | null | | jc | justify-content | string | null | | ta | text-align | string | null |

iii) Column props

✨ The responsive props (xs, sm, md, lg, xl) when present alter the flex shorthand property of the Column. More specifically the third parameter which corresponds to the flex-basis. For example if you pass only md="33%" we have in the code:

const Column = styled.div`
  ....
  flex: ${({ xl }) => (xl ? `0 0 ${xl}` : 1)};
  @media screen and (max-width: 992px) {
    flex: ${({ md }) => md && `0 0 ${md}`};
  }
  ....
  @media screen and (max-width: 576px) {
    flex: ${({ xs }) => xs && `0 0 ${xs}`};
  }

`

and the result is (see the following table for defaults):

  const Column = styled.div`
  ....
  flex:  1;
  @media screen and (max-width: 992px) {
    flex: 0 0 33%;
  }
  ....
  @media screen and (max-width: 576px) {
    flex: 0 0 100%;
  }

`

You can pass in breakpoint props (xs, sm, ...) any value that is valid for width and height CSS properties. Meaning px, em, %...

| name | extra info | type | default | | --------- | ------------------------------------------------------------------------------------------- | ------ | ------- | | flex | true = display: flex, false = display: block | bool | false | | xs | Screen width <= 576px. By default Columns take the whole Row in this breakpoint (xs="100%") | string | "100%" | | sm | Screen width <= 768px | string | null | | md | Screen width <= 992px | string | null | | lg | Screen width <= 1200px | string | null | | xl | Screen width > 1200px. By default Columns occupy equal space inside a Row (flex-basis: 1). | string | null | | h | height | string | null | | m | margin | string | null | | p | padding. If you use gutters on the parent Row component this property will be overridden | string | null | | alignSelf | align-self. as is reserved if you're wondering 😠 | string | null | | ta | text-align | string | null | | c | color | string | null | | bc | background-color | string | null |

iv) Centered

A simple utility component that uses flexbox to center vertically and horizontally the content. By default has height: 100%.

Centered props

| name | extra info | type | default | | ---- | ---------------- | ------ | -------- | | fd | flex-direction | string | "column" | | ai | align-items | string | "center" | | h | height | string | "100%" | | m | margin. | string | null | | p | padding | string | null | | ta | text-align | string | null | | c | color | string | null | | bc | background-color | string | null |

2. Button

A slightly round button that is similar to the Bootstrap 4 button. It calculates the background-color on hover and adds an outline from the bc prop you specify. If you want to extend it with styled(Button), I suggest to use the bc prop to keep this functionality.

Example
import React from "react";
import { Button } from "already-styled-components";

export default () => (
  <div>
    <Button>Click me</Button>
    <Button transparent c="black">
      "Icon" button
    </Button>
  </div>
);
Example (extending Button)
import React from "react";
import styled from "styled-components";
import { Button } from "already-styled-components";

const Center = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
`;
const OrangeButton = styled(Button)`
  border-radius: 0px;
  background-color: orange;
  color: black;
`;
const PinkButton = styled(Button)`
  border-radius: 0px;
  font-size: 24px;
`;
export default () => (
  <Center>
    <OrangeButton>Not so good</OrangeButton>
    <PinkButton bc="pink" c="black">
      Better
    </PinkButton>
  </Center>
);
Button props

| name | extra info | type | default | | --------------- | --------------------------------------------------------------------------------------- | ------ | --------- | | transparent | Transparent background-color and no transitions. You can use it as an icon button | bool | false | | c | color | string | "#FFF" | | bc | background-color | string | "#00AFB1" | | hc | hover color | string | null | | br | border-radius | string | "20px" | | ff | font-family | string | "inherit" | | fs | font-size | string | "20px" |

3. Navbar

A render props component that renders a sticky navigation bar with a mobile full screen menu. More specifically renders by default a DesktopList and a MobileList component. You can pass the links via the children prop. If you want more control and customization you can use the DesktopListEmpty or MobileListEmpty. The last two render only a button that open and closes the mobile menu. Obviously you can provide you own implementations, but I believe the empty lists can cover a lot of scenarios.

Note: The Navbar component registers an IntersectionObserver if the fixed property is set to true. In order for it to work on Safari you need this polyfill. The easiest way is to include the following script before the browser parses your JavaScript (at the head of the document):

<script src="https://polyfill.io/v2/polyfill.min.js?features=IntersectionObserver"></script>
Examples
Prop tables
Example 1 (without any customizations)
import React from "react";
import styled from "styled-components";
import { Container, Navbar } from "already-styled-components";

const Brand = styled.div`
  font-size: 36px;
  font-style: italic;
  color: white;
`;
export default () => (
  <Container h="200vh" fluid>
    <Navbar brand={<Brand>Styled Components</Brand>}>
      <a href="/">Home</a>
      <a href="/About">About</a>
      <a href="/Contact">Contact</a>
    </Navbar>
  </Container>
);
Navbar props

| name | extra info | type | default | | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------- | | desktopList | A function that returns the desktop navbar (render prop) | function | props => <DesktopList {...props} /> | | mobileList | A function that returns the mobile navbar (render prop) | function | props => <MobileList {...props} /> | | brand | The brand name or logo positioned at the left. | A React element | null | | fixed | The desktop list is actually positioned sticky not fixed. When it's true it doesn't change the position property anymore but instead performs a height transition when the user scrolls down. I'll change the name in version 3 to make more sense. | bool | true | | children | The links that the desktop/mobile lists will render | A React element or more | null | | c | color | string | "#FFF" | | bc | background-color | string | "#313131" | | hc | :hover color | string | "orangered" |

Example 2 (extending the default DesktopList)

In this example we change the colors of the DesktopList when we scroll down. That is, if the Navbar is "fixed top" which is the default behavior.

import React from "react";
import styled from "styled-components";
import { Container, Navbar, DesktopList } from "already-styled-components";

const Brand = styled.div`
  font-size: 36px;
  font-style: italic;
  color: white;
`;

const WhiteWhenFixed = styled(DesktopList)`
  box-shadow: 0 0 3px 0 black;
  transition: all 0.3s ease-in-out !important;
  background-color: ${({ fixedTop }) => fixedTop && `white`};
  a,
  div {
    color: ${({ fixedTop }) => fixedTop && `black`};
  }
  path {
    fill: ${({ fixedTop }) => fixedTop && `black`};
  }
`;
export default () => (
  <Container fluid h="200vh" bc="beige">
    <Navbar
      brand={<Brand>Styled Components</Brand>}
      desktopList={props => (
        <WhiteWhenFixed {...props} suppressClassNameWarning />
      )}
    >
      <a href="/">Home</a>
      <a href="/About">About</a>
      <a href="/Contact">Contact</a>
    </Navbar>
  </Container>
);

3. i) DesktopList props

| name | extra info | type | default | | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | --------------------------- | | showMobile | A function that shows the mobile menu | function | null | | links | The children of the Navbar if any. | A React element or more | None, it's required | | brand | The brand name or logo positioned at the left of the desktop list. | A React element | null | | fixedTop | Is the Navbar "fixed top" now? | bool | false | | fixedBreakpoint | A ref used by the IntersectionObserver of the Navbar | node | None, it's required | | mobileBreakpoint | A number that indicates the screen size in which we hide the desktop links and show the hamburger button that opens the mobile menu. | number | 980 | | timeout | The timeout prop of the CSSTransition. It specifies how long the Navbar will transition when it enters the "fixed top" state (the user scrolls down) and when leaves (the user scrolls at the top of the screen). | object | { enter: 150, exit: 150 } | | className | For extending with styled-components. | string | null | | c | color | string | "#FFF" | | bc | background-color | string | "#1D1D1D" | | hc | :hover color | string | "orangered" |

3. ii) MobileList props

| name | extra info | type | default | | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------- | --------------------------- | | links | The children of the Navbar, if any | A React element or more | None, it's required | | mobileMenuVisible | Is the mobile menu visible now? | bool | None, it's required | | hideMobile | A function that hides the mobile menu. | function | null | | timeout | The timeout prop of the CSSTransition. It specifies how long will animate the mobile list when enters and leaves the screen. | object | { enter: 300, exit: 150 } | | className | For extending with styled-components. | string | null | | c | color | string | "#FFF" | | bc | background-color | string | "#1D1D1D" | | hc | :hover color for the links | string | "orangered" |

Example 3 (using and extending the MobileListEmpty)

In this example we put our own content in the mobile list and change the enter transition from fade-in to slide-down. Check these examples for more ideas.

import React from "react";
import { Link } from "react-router-dom";
import styled from "styled-components";
import {
  Container,
  Row,
  Column,
  Centered,
  Navbar,
  MobileListEmpty
} from "already-styled-components";

const MobileListContent = styled(MobileListEmpty)`
  &.mobile-list-enter {
    transform: translateY(-100vh);
  }
  &.mobile-list-enter-active {
    transform: translateY(0);
    transition: transform 0.5s ease-out;
  }
  &.mobile-list-exit {
    transform: translateY(0);
  }
  &.mobile-list-exit-active {
    transform: translateY(-100vh);
    transition: transform 0.3s ease-out;
  }
`;
const MobileLink = styled(Link)`
  font-size: 36px;
  text-decoration: none;
  color: white;
  :hover {
    color: #cca43b;
  }
`;

export default () => (
  <Container h="200vh" fluid>
    <Navbar
      c="white"
      bc="#242F40"
      hc="#CCA43B"
      mobileList={props => (
        <MobileListContent {...props} timeout={{ enter: 500, exit: 300 }}>
          <Centered h="100%">
            <h2>My mobile links!</h2>
            <MobileLink to="/">Home</MobileLink>
            <MobileLink to="/about">About</MobileLink>
            <MobileLink to="/contact">Contact</MobileLink>
          </Centered>
        </MobileListContent>
      )}
    >
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
      <Link to="/contact">Contact</Link>
    </Navbar>
    <Row>
      <Column h="100vh">
        <Centered bc="pink" c="white">
          <h1>Slide-down navbar</h1>
        </Centered>
      </Column>
    </Row>
  </Container>
);

3. iii) DesktopListEmpty props

| name | extra info | type | default | | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------------------------- | | showMobile | A function that shows the mobile menu | function | null | | children | The children of the desktop list (the links). | node | null | | fixedTop | Is the desktop list "fixed top" now? | bool | false | | fixedBreakpoint | A ref used by the IntersectionObserver of the Navbar | node | None, it's required | | mobileBreakpoint | A number that indicates the screen size in which we hide the desktop links and show the hamburger button that opens the mobile menu. | number | 980 | | timeout | The timeout prop of the CSSTransition. It specifies how long the desktop list will transition when it enters the "fixed top" state (the user scrolls down) and when leaves (the user scrolls at the top of the screen). | object | { enter: 150, exit: 150 } | | className | For extending with styled-components. | string | null | | c | color | string | "#FFF" | | bc | background-color | string | "#1D1D1D" | | hc | hover color of the hamburger icon. | string | "orangered" |

3. iv) MobileListEmpty props

| name | extra info | type | default | | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | --------------------------- | | children | The children of the mobile list (the links) | node | null | | mobileMenuVisible | Is the mobile menu visible now? | bool | None, it's required | | hideMobile | A function that hides the mobile menu. | function | null | | timeout | The timeout prop of the CSSTransition. It specifies how long will animate the mobile list when enters and leaves the screen. | object | { enter: 150, exit: 150 } | | className | For extending with styled-components. | string | null | | c | color | string | "#FFF" | | bc | background-color | string | "#1D1D1D" | | hc | hover color for the close mobile menu icon. | string | "orangered" |

More Examples using the DesktopListEmpty and MobileListEmpty

4. AnchorLink

A button that'll smooth scroll to the specified section on click. Similar to GitHub heading links in markdown. Under the hood, is basically a slightly different Button component with a transparent prop. You can also provide an offset prop (if you have a fixed/sticky navbar) or a callback (e.g close a modal or a menu after click).

Example
import React from "react";
import styled from "styled-components";
import { AnchorLink } from "already-styled-components";

const Navigation = styled.nav`
  height: 74px;
  background-color: #1d1d1d;
  position: sticky;
  top: 0;
`;
const FirstSection = styled.div`
  height: 50vh;
  color: white;
  background-color: #333;
`;
const SecondSection = styled.div`
  height: 150vh;
  background-color: azure;
`;
export default () => (
  <div>
    <Navigation />
    <FirstSection id="first-section">
      <AnchorLink scrollTo="first-section" c="white">
        First section
      </AnchorLink>
      <p>Close :(</p>
    </FirstSection>
    <SecondSection id="second-section">
      <AnchorLink scrollTo="second-section" offset={74}>
        Second section
      </AnchorLink>
      <p>Perfect!</p>
    </SecondSection>
  </div>
);
AnchorLink props

| name | extra info | type | default | | ------------ | ------------------------------------------------------ | -------- | ----------------------- | | scrollTo | It's the section id without the # character | string | None, it's required | | offset | You can use it if you have a fixed navbar for example | number | 0 | | callback | A function that you want to execute after the click. | function | null | | children | | node | null | | fs | The font size for the text and the width of the SVG | string | "20px" | | c | color. It's the text color | string | "#000" | | o | opacity | number | 1 |

5. Floating Action Button

A material floating action button that represents the primary action of the page. You can pass as child your own icon (it's empty by default). The default position is at the bottom right corner of the screen. It has a ripple effect on click and an optional pulse animation to draw the attention of the user.

Example with icons from fortawesome
npm i @fortawesome/react-fontawesome @fortawesome/free-regular-svg-icons @fortawesome/fontawesome-svg-core
import React from "react";
import { Fab } from "already-styled-components";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPaperPlane, faStar } from "@fortawesome/free-regular-svg-icons";

export default () => (
  <div>
    <Fab aria-label="send email" onClick={e => console.log("Email sent!")}>
      <FontAwesomeIcon icon={faPaperPlane} />
    </Fab>
    <Fab
      bc="#20c7b6"
      w="50px"
      fs="22px"
      t="20px"
      pulse
      aria-label="do more stuff"
      onClick={() => console.log("More stuff done!")}
    >
      <FontAwesomeIcon icon={faStar} />
    </Fab>
  </div>
);
Fab props

| name | extra info | type | default | | ---------- | ---------------- | ------ | --------- | | ripple | | bool | false | | pulse | | bool | true | | c | color | string | "#FFF" | | bc | background-color | string | "crimson" | | fs | font-size | string | "30px" | | w | width | string | "80px" | | t | top | string | null | | r | right | string | "3%" | | b | bottom | string | "3%" | | l | left | string | null | | zi | z-index | number | 1 |

6. Progress Bar

A YouTube/Stack Overflow like progress bar, positioned at the top of the screen.

Example
import React from "react";
import styled from "styled-components";
import { ProgressBar, Button } from "already-styled-components";

const Section = styled.section`
  min-height: 90vh;
  display: flex;
  align-items: center;
  justify-content: center;
`;

export default class Home extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      loading: true
    };

    this.toggleProgressBar = this.toggleProgressBar.bind(this);
  }

  toggleProgressBar() {
    this.setState({ loading: !this.state.loading });
  }

  render() {
    const { loading } = this.state;
    return (
      <div>
        <ProgressBar bc="rebeccapurple" visible={loading} />
        <Section>
          <Button bc="rebeccapurple" onClick={this.toggleProgressBar}>
            {loading ? "Stop" : "Start"} the progress bar
          </Button>
        </Section>
      </div>
    );
  }
}
ProgressBar props

| name | extra info | type | default | | ----------- | ---------------- | ------ | -------- | | visible | | bool | true | | bc | background-color | string | "orange" | | zi | z-index | number | 1 |

Extending styles

Source

You may want to change something in a component that a prop doesn't cover (or just don't want to use props). For example the ProgressBar component is positioned fixed at the top of the screen. You may want to place it at the top of a section.

import React from "react";
import styled from "styled-components";
import { ProgressBar } from "already-styled-components";

const Section = styled.section`
  position: relative; /* important for the container */
  min-height: 40vh;
  background-color: ${({ bc }) => bc};
  display: flex;
  align-items: center;
  justify-content: center;
`;
const CustomProgressBar = styled(ProgressBar)`
  position: absolute;
  top: 100%;
`;
export default () => (
  <div>
    <ProgressBar />
    <Section bc="beige">
      <h2>
        The orange progress bar is at the default position (fixed top of the
        screen)
      </h2>
    </Section>
    <Section bc="azure">
      <h2>
        The black one (CustomProgressBar) is at the bottom of this section.
      </h2>
      <CustomProgressBar bc="black" />
    </Section>
  </div>
);

Note for extending components with styled(Component): If we take the ProgressBar example above, the original ProgressBar has top: 0. If you want to position it at the bottom of the section, you'll have to override the top property with top: 100% in order to work. For example, it won't work with bottom: 0.