Skip to content

gregolai/pu2

Repository files navigation

pu2

Build Status NPM version Standard Version


Me

Style Lib

Everything goes through <Box>

// src/client/MyButton.tsx
import React from 'react';
import { Box } from 'pu2';


// Renders a <div> element with a button role
export const MyButton = ({ children, onClick }) => (
	<Box
		role="button"
		cursor="pointer"
		display="flex"
		alignItems="center"
		justifyContent="center"
		onClick={onClick}
	>
		{children}
	</Box>
);

// Renders a <button> element with some icon
export const MyButton2 = ({ children, icon, onClick }) => (
	<Box as="button" onClick={onClick}>
		{icon}
		{children}
	</Box>
);

// Passing some css as a prop will override style props (renders a black button with white text)
const css = { color: 'white', background: 'black' };
export const MyButton4 = ({ children, onClick }) => (
	<Box color="orange" css={css} onClick={onClick}>
		{children}
	</Box>
);

// Get fancy. Generate classnames on-the-fly, including media queries and sub-selectors.
const css = {
	color: 'lightblue',
	
	// Match descendent children (notice the space before the selector)
	' span': {
		color: 'green',

		'[data-value]': { color: 'silver' }, // Match attribute

		'.x': { color: 'wheat' } // Match classname (no space before the selector)
	},
	' .b': { color: 'orange' },

	// Match immediate children
	'>span': { color: 'blue' },
	'>.b': {
		color: 'yellow',

		':hover': { color: 'cyan' } // Match element state
	},

	// Match a media query
	'@media screen and (max-width: 600px)': {
		color: 'magenta',

		'>span': { color: 'red' }
	}
}
export const MyButton5 = ({ onClick, prefix }) => (
	<Box css={css} onClick={onClick}>
		lightblue...or magenta when <=600px screen width
		<Box className="a">black</Box>
		<Box as="span">
			blue...or red when <=600px screen width
			<Box className="b">orange</Box>
		</Box>
		<Box className="b">
			yellow...or cyan when hovering
			<Box as="span">green</Box>
			<Box as="span" data-value="10">silver</Box>
			<Box as="span" className="x">wheat</Box>
		</Box>
		<Box className="b">
	</Box>
)

Basic SSR

// src/client/App.ts
import React from 'react';
import { Box } from 'pu2/style-lib';

export const App = () => (
	<Box background="blue" p="16px">
		<Box color="red" background="white" p="8px">
			Text
		</Box>
	</Box>
);
// src/client/main.client.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserStyleProvider } from 'pu2/style-lib';
import { App } from './App';

ReactDOM.hydrate(
	<BrowserStyleProvider>
		<App />
	</BrowserStyleProvider>,
	document.body
)
// src/server/main.server.ts
import React from 'react';
import express from 'express';
import { renderToString } from 'react-dom/server';
import { SSRStyleProvider, SSRStyleCollector } from 'pu2/style-lib/server';
import { App } from '../client/App';

const renderSSR = ({ appHtml, styleHtml }) => `
<!DOCTYPE html>
<html lang="en">
	<head>
		<title>My App</title>
		${styleHtml}
	</head>
	<body>
		${appHtml}
	</body>
</html>
`;

const server = express();

server.get('/', async (req, res) => {
	const collector = new SSRStyleCollector();
	const appHtml = renderToString(
		<SSRStyleProvider collector={collector}>
			<App />
		</SSRStyleProvider>
	);
	const styleHtml = collector.getHtml();

	res.status(200)
		.set({ 'Content-Type': 'text/html' })
		.end(renderSSR({ appHtml, styleHtml }));
});
server.listen(3000);

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published