Never Punch Manticores

    react-jsx-template
    TypeScript icon, indicating that this package has built-in type declarations

    1.0.13-0 • Public • Published

    react-jsx-template

    react + react-jsx-template = modularity and encapsulation

    React component for style encapsulation. It helps you create components with scoped styles, also compatible with material-UI components. We would agree that writing CSS for React would be a lot easier if we didn't have to worry about conflicting style rules, this component does exactly that.

    If you're a Vue.js developer transitioning to React.js you will love this powerful yet simple component. It works like the <template> tag in Vue.js, but in this case you write both your markup and stylesheet inside it.

    You might want to read more about how this component achieves encapsulation, or move on you're fine without this paragraph. 'react-jsx-template' works with the Shadow DOM API and essentially renders the content of your component within the Shadow DOM of a 'root' element. Ok that's enough talk, proceed to see how all this might be useful to you.

    installation

    If you have node installed on your computer, run;

    npm install react-jsx-template

    peer dependencies

    This package requires that you have the following packages installed in your project;

    • Material-UI components version: ^"4.10.1" for reusable UI components. More information here

      to install run;

      npm install @material-ui/core
    • React library. It comes by default if you scaffold your project on CRA. More information here

      to install run;

      npm install react

    Usage

    Quick links

    | Structuring your markup | Custom setup | Styling the root element | Variable CSS selectors | Variable CSS properties | Variable CSS values | Variable CSS properties | Dynamic pseudo-element styling | Dynamic media queries

    Now we're all setup, to use the 'react-jsx-template' import it at the top of your script.

    import {Template} from 'react-jsx-template'

    Structuring your markup

    You can then use it in the render function of your component by structuring it this way;

    // component showing how to structure your markup
    render() {
        return (
            <Template>
     
                {/* the root element can be any element or component except <style> */}
                <root>
     
                    {/* this is where the content of your component goes */}
                    <p>Hello world!</p>
     
                    <p>
                        Everything within the 'root' element will be regarded as the 
                        content of this component.
                    </p>
                </root>
     
                <style>
                {`
                    selector {property: value;}
                `}
                </style>
            </Template>
        )
    }

    Essentially, our <template> should contain 2 child elements;

    • The root element, where we write our markup.
    • A <style> element to contain our CSS rules.
    // component with scoped styles, using material-ui component library
    render() {
        return (
            <Template>
                <div> {/* this div is the root element */}
     
                    {/* this is the content */}
                    <p>Red colored content, try it</p>
                </div>
     
                <style>
                {`
                    div {color: red;}
                `}
                </style>
            </Template>
        )
    }

    The <Template> tag does not get mounted to the DOM, so if you check your dev tools you won't see it. However, the root element gets mounted to the DOM and contains all the other elements of our component.

    Custom setup

    You can use material-ui styled components by default, the inline styles will be preserved. To use a different component library, you need to setup a custom 'StylesProvider' the setup is explained below.

    Create a template.js file in your './src' directory, and write the following code in it;

    // template.js
    import {StylesProvider} from 'location of user defined styles provider'
    import {initializeTemplate} from 'react-jsx-template'
     
    const Template = initializeTemplate(StylesProvider)
    export default Template

    You can now use it in your components;

    // your component
    import Template from './template.js'
    import {Item} from 'other component library'

    and in the render function we can have something like this;

    // component with scoped styles, using other component library
    render() {
        return (
            <Template>
                <Item {/* this component is the root element */}
                 display = 'flex'
                 justifyContent = 'space-between'
                 width = '100%'
                 padding = '0.5rem'
                 background = '#06397d'
                >
                    <Item className='red box' height='100%'></Item>
                    <Item className='yellow box' height='100%'></Item>
                </Item>
     
                <style> {/* user defined style rules override component library's inline styles */}
                {`
                    .red {background: #911f1e;}
     
                    .yellow {background: #fcdfa3;}
     
                    .box {height: 50%;}
                `}
                </style>
            </Template>
        )
    }

    Styling the root element

    Styling the root element of your component can be done using the ':host' selector. This is because encapsulation is done using the shadow DOM API under the hood. You don't need prior knowledge of that to use this component, but you can check that out later if you want.

    // styling the root element
    render() {
        return (
            <Template>
                <div> {/* this is the root element */}
                    The root element has red text.
                </div>
     
                <style>
                {`
                    :host {color: red;}
                `}
                </style>
            </Template>
        )
    }

    Variable CSS selectors

    We have our CSS inside our JS file, and this allows us to play around with the CSS, using javascript variables as CSS selectors in our component styling, take a look;

    // JS variable as CSS selector
    render() {
        // we can change the value of 'target' dynamically to 'green' or 'blue'
        let target = 'red'
     
        return (
            <Template>
                <div>
                    <p className={target}>
                        This paragraph has a variable className and a CSS selector that always matches its className and applies persistent styling rules, eliminating the need for an additional className.
                    </p>
                </div>
     
                <style>
                {`
                    p.${target} {...persistent styling rules}
     
                    .red {color: red;}
                    .green {color: green;}
                    .blue {blue: blue;}
                `}
                </style>
            </Template>
        )
    }

    Variable CSS properties

    We can also use this concept to implement dynamic CSS properties in our component styles

    // JS variable as CSS property
    render() {
       // we can dynamically alternate the value of 'property' between 'border-color' and 'color'
       let property = 'border-color'
     
       return (
           <Template>
               <div>
                   <p className='someClass'> This paragraph can either have a blue text color or a blue border color</p> 
               </div>
     
               <style>
               {`
                   .someClass {${property}: blue;}
               `}
               </style>
           </Template>
       )
    }

    Variable CSS values

    With the same technique, we can have dynamic CSS values in our component styles

    // JS variable as CSS value
    render() {
       // we can dynamically change 'value'
       let value = '10%'
     
       return (
           <Template>
               <div>
                   <p className='someClass'> The CSS value of the height of this paragraph can be directly manipulated using Javascript.</p> 
               </div>
     
               <style>
               {`
                   .someClass {height: ${value};}
               `}
               </style>
           </Template>
       )
    }

    Dynamic pseudo-element styling

    This makes controlling the CSS styles of pseudo-elements a breeze, see an example;

    // JS variable as CSS selector
    render() {
        // we can dynamically change the value of 'size' to 'medium' or 'large'
        let size = 'small'
     
        return (
            <Template>
                <div>
                    <p className={size}>The :before pseudo-element of this paragraph has persistent and variable
                    style rules.</p>
                </div>
     
                <style>
                {`
                    .${size}:before {
                        content: '';
                        position: absolute;
                        height: 10px;
                        background: crimson;
                    }
     
                    .small:before {width: 10%;}
                    .medium:before {width: 25%;}
                    .large:before {width: 40%;}
                    .x-large:before {width: 60%;}
                `}
                </style>
            </Template>
        )
    } 

    Dynamic media queries

    We can also experiment with dynamic media queries, see an example;

    // JS variable as media query breakpoint
    render() {
        // we can dynamically adjust the breakpoint of the media query, thereby activating or deactivating it.
            let breakpointMobile = '720px'
            let breakpointDesktop = '1280px'
     
        return (
            <Template>
                <div>
                    <p> You can alter the breakpoint to display desktop view on mobile and vice-versa. </p>
                </div>
                
                <style>
                {`
                    @media screen and (max-width: ${breakpointMobile}) {
                        // mobile styling
                    }
     
                    @media screen and (min width: ${breakpointDesktop}) {
                        // desktop styling
                    }
                `}
                </style>
            </Template>
        )
    } 

    For additional support, follow me on twitter @onepetercollins or github. You can share your ideas and cool projects, I'd love to see them.

    If you made it this far, this component is useful to you. I will appreciate your donations towards the maintenance of this package. Email me

    Install

    npm i react-jsx-template

    DownloadsWeekly Downloads

    3

    Version

    1.0.13-0

    License

    ISC

    Unpacked Size

    26.7 kB

    Total Files

    6

    Last publish

    Collaborators

    • onepetercollins