0.1.5 • Published 9 months ago

css-template-components v0.1.5

Weekly downloads
-
License
-
Repository
-
Last release
9 months ago

CSS-TEMPLATE-COMPONENTS

A simple CSS in JS library for client and server-side React Components

Github: @adaup1/css-template-components

INSTALLATION

npm
npm i css-template-components

yarn yarn add css-template-components

pnpm pnpm add css-template-components

SERVER-SIDE RENDERING SETUP (SKIP IF CLIENT-SIDE ONLY)

Using css-template-components with server-side rendering requires just a *tiny bit of extra setup. If you are only using css-template components on the client-side you can skip this section. For this documention, we'll be using Next.js with App Router.

1. Import the getServerStyles function from "css-template-components/server" into the root component of the project. In Next.js using App Router, this will the root layout.tsx.

import { getServerStyles } from "css-template-components/server";

2. Inside the RootLayout Component, call getServerStyles and assign it to a variable

const serverStyles = getServerStyles();

3. Add a tag inside the of your RootLayout with a child of { serverStyles } or whatever you named your variable. Optionally, you can add an id.

Here is an example full implementation:

import { getServerStyles } from "css-template-components/server ";

export default function RootLayout({ children }) {
  const serverStyles = getServerStyles();

  return (
    <html>
      <head>
        <style>{serverStyles}</style>
      </head>
      <body>{children}</body>
    </html>
  );
}

Using Styles

Css-template-components uses a function called styled which returns a React Component with CSS styles.

No need to add a className since styled automatically adds a unique className to the component. Under the hood, css-template-components generates style sheets with these classNames. This means you don't need to mannually create any style sheets.

If you are familiar with tagged template strings in styled-components, you'll find using css-template-components very familiar, with only a few small differences.

Styled-components is an incredible library, but it uses React.context under the hood, which prevents it from being used in Next.js server components.

For server components

import { styled } from "css-template-components/server";

For client components

import { styled } from "css-template-components/client";

From here on out, usage is the same!

The styled function requires two arguments: First Argument:

  • A JSX element string (keyof JSX.IntrinsicElements) (Example: 'div', 'p', 'a', 'ul', ..etc )
  • A React Components (React.ComponentType)

Second Argument:

  • A tagged template string (For static styles)
  • An callback returning a tagged template string (For dynamic styles)

Tagged template strings should contain valid CSS

Code Examples

Example 1

Create a p element with static styles inside a client component:

"use client";
import { styled } from "css-template-components/client";

export const MyComponent = () => {
  return <StyledParagraph>My styles are static!</StyledParagraph>;
};

const StyledParagraph = styled(
  "p",
  `
  padding: 1rem;
  color: purple;
`
);

Example 2

Create a div element with dynamic styles inside a server component:

import { styled } from "css-template-components/server";

export const MyComponent = () => {
  return (
    <StyledDiv name="Frank">
      My styles are dynamic based on my properties!
    </StyledDiv>
  );
};

const StyledDiv = styled(
  "div",
  ({ name }) => `
  background-color: ${name === "Frank" ? "#ff0000" : "#00ffff"};
`
);

Example 3

Style a child component inside the parent with static styles.

import { styled } from "css-template-components/server";

// Child component that will be styled in the parent
const ChildComponent = () => {
  return <>I'm the child!</>;
};

// The parent component that returns the styled version of ChildComponent (see below for styles)
export const ParentComponent = () => {
  return <StyledChildComponent />;
};

// Styled ChildComponent with static styles for use inside ParentComponent
const StyledChildComponent = styled(
  ChildComponent,
  `
 background: #ff0000;
 color: white;
 padding: 1rem;
`
);

Example 4

This is the most complex example. We'll be creating a ChildComponent and ParentComponent. The ChildComponent will include a styled div with static styles. The ParentComponent will include a styled version of the ChildComponent with dynamic styles. We'll even add a touch of Typescript.

"use client";
import { styled } from "css-template-components/client";

// Child component that will be styled in the parent
const ChildComponent = ({ name, age }: { name: string, age: number }) => {
  return (
    <>
      <StyledFlexContainer>
        <p>{`name: ${name}`}</p>
        <p>{`age: ${age}`}</p>
      </StyledFlexContainer>
    </>
  );
};

// A styled div element with static styles for use inside ChildComponent
const StyledFlexContainer = styled(
  "div",
  `
  display: flex;
  gap: 1rem;
  padding: 0.5rem;
  width: 100%;
  color: black;
`
);

// Some data
const people = [
  { name: "Marissa", age: 28, id: 1 },
  { name: "Dave", age: 34, id: 2 },
  { name: "Ronald", age: 54, id: 3 },
  { name: "Sarah", age: 47, id: 4 },
];

// The parent component that will map over the data and return the styled version of ChildComponent (see below for styles)
export const ParentComponent = () => {
  return (
    <>
      {people.map((person) => (
        <StyledChildComponent
          name={person.name}
          age={person.age}
          id={person.id}
          key={person.id}
        />
      ))}
    </>
  );
};

// Styled ChildComponent with dynamic styles based on props for use inside ParentComponent
const StyledChildComponent = styled(
  ChildComponent,
  ({ name, age }: { name: string, age: number }) => `
  background-color: ${name === "Ronald" ? "green" : "blue"};

  :hover {
    background-color: yellow;
  }

  > * {
    color: ${age === 34 && "red"};
  }
`
);

Tips and Tricks

Callbacks still work for static styles, just don't pass in any props.

Example:

// Static styles with string for second argument
const StyledDiv = styled(
  "div",
  `
  padding: 1rem;
`
);

// Static styles with callback for second argument
const StyledDiv = styled(
  "div",
  () => `
  padding: 1rem;
`
);
className override

Passing a custom className prop won't break css-template-components. Just keep in mind it may result in extra css-generation if more than one element shares the same css properties.

Example:

"use client";
import { styled } from "css-template-components/client";

export const MyComponent = () => {
  return (
    <StyledParagraph className="customClassName">
      I have a custom className!
    </StyledParagraph>
  );
};

const StyledParagraph = styled(
  "p",
  `
  padding: 1rem;
  color: purple;
`
);

Thank you for choosing css-template-components!

ENJOY!

0.1.5

9 months ago

0.1.4

10 months ago

0.1.3

10 months ago

0.1.2

11 months ago

0.1.1

11 months ago

1.0.7

11 months ago

1.0.6

11 months ago

1.0.5

11 months ago

1.0.4

11 months ago

1.0.3

11 months ago

1.0.2

11 months ago

1.0.1

11 months ago