@guardian/guui

1.4.2 • Public • Published

guui

Frontend rendering framework for theguardian.com.

Slack channel: #dotcom-future

Requirements

Install

$ npm install @guardian/guui

Configure

Provide h() for all JSX modules

$ npm install babel-plugin-provide-modules
{
  "plugins": [
    ["provide-modules", {
      "@guardian/guui": ["h"]
    }]
  ]
}

Use Webpack loaders

// webpack.config.js

module.exports = {
    
    // ...
    
    resolveLoader: {
        modules: [
            path.resolve('node_modules', '@guardian', 'guui', 'dist', 'lib', 'loaders'),
            'node_modules'
        ]
    },
    
    module: {
        rules: [
            {
                test: /\.svg$/,
                use: ['guui-svg-loader']
            },
            {
                test: /\.css$/,
                use: ['guui-css-loader']
            }
        ]
    }
}

API

JSX

Components are written using JSX

export default () => <h1>Hello World</h1>

Styling

You may declare your styles in separate *.css files. Under the hood, guui generates CSS using Emotion. As a result, you may define your styles using the Emotion API.

// header.css
 
.heading {
    color: ghostwhite;
    
    &:hover {
        color: palevioletred;
    }
}
// header.jsx
 
import { heading } from './header.css'
 
export default () => <h1 style={heading}>Hello World</h1>

Exentions to standard CSS

Some Sass-like features are available to use in .css files.

Custom property and media queries

Both of these are transpiled to more compatible CSS in compilation:

@custom-media --unusual-breakpoint (max-width: 30em);
 
:root {
    --my-value: 20px;
}
 
.big {
    font-size: var(--my-value);
	 
    @media (--unusual-breakpoint) {
        color: hotpink;
    }
}

@apply

To avoid too much duplicating of rules in some circumstances, the @apply rule can be used:

:root {
    --button: {
        border-radius: 28px;
    };
    --news-colour: blue;
}
 
.button {
    @apply --button;
}
 
.button--news {
    @apply --button;
    background-color: --news-colour;
}

SVGs

import MySVG from './my-svg.svg';

SVGs are loaded using guui-svg-loader.js, which runs them through svgo then returns them as JSX objects.

You can use the JSXified SVG as a normal JSX import:

<!-- my-svg.svg -->
<svg xmlns="http://www.w3.org/2000/svg" width="320" height="60"><path ... /></svg>
import MySVG from './my-svg.svg'
 
export default () => <div><MySVG /></div>
 
// <div><svg width="320" height="60"><path ... /></svg></div>

Styling the SVG

<MySVG style={{ fill: "red" }} />
import MySVG from './my-svg.svg'
 
const style = {
    color: 'red'
}
 
export default () => <MySVG style={style} />
 
// <svg style="color: red"><path ... /></svg>

Rendering

Server

import { server } from '@guardian/guui';
import Application from './components/app';
 
const app = server();
 
export const render = (props) => {
    const body = app.renderToString(<Application {...props} />);
    const css = app.extractCriticalCss(body);
 
    return `
        <!DOCTYPE html>
        <html>
            <head>
                ${css}
                <script>
                    window.props = ${JSON.stringify(props)};
                </script>
            </head>
            <body>
                ${body}
            </body>
        </html>
    `.trim();
};

Browser

import { render } from '@guardian/guui';
 
const container = document.body;
 
const renderApp = () => {
    const props = window.props;

    if (container) {
        render(
            <Application {...props} />,
            container.parentElement,
            container
        );
    }
};
 
renderApp();

Readme

Keywords

none

Package Sidebar

Install

npm i @guardian/guui

Weekly Downloads

20

Version

1.4.2

License

Apache-2.0

Last publish

Collaborators

  • joecowton1
  • guardian-developers
  • akash1810
  • reetta
  • sndrs
  • mxdvl