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

@jorsek/content-portal-themes

v4.0.1

Published

## Structure

Downloads

20

Readme

Themes

Structure

+-- base
+-- dark
+-- light
+-- whitelabel
...

The dark and light themes independently inherit from the base theme using the npm deepmerge package.

  • base should never contain color properties and should only contain structural (grid, flex, position, etc...) CSS
  • dark, light, and any other color themes should contain mostly color specifications but should avoid containing structural CSS changes. This should be limited in scope.
  • None of the basic themes should make use of :before or :after pseudo-selectors.
    • Those are powerful tools for drastically changing the layout structure and presentation of a specific tenant. They should be reserved exclusively for tenant theme CSS.
  • Tenant themes will likely contain all of the above and css adjustments (position, top, margins, padding)

Rules

  1. Never use negative margins in the base themes. Customer overrides may require it (such as Vyatta's hero image and background color) but should be avoided if at all possible.
  2. Never use percentages unless It's a base 8 root %. (100%, 50%, 25%, 12.5%, 6.25% 3.125%)
    • 33% sucks for this very reason. Use it sparingly.
    • Instead, try to use flex properties and flex-basis when forced to use awkward percentages.)
  3. Use rems whenever possible. The html base font-size should be set by default to 16px. Scale everything off rems that way.
  4. Use flex for general layout properties. Use grid for specific use-cases with lists and items that need to be fixed to a certain number. grid is an extension of flex and anything can be achieved with flex that you can with grid albeit less rigid.

BEM

BEM stands for "{Block}-{Element}-{Modifier}". We use a slightly modified variation of BEM for CSS naming, but it's good to understand BEM and why it exists. The reason for this is we want and invite people to apply their own styling.

Typical jss/sass stylesheet generation obfuscates the names of CSS classes. ./media/jss.png

What we generate are semantic naming of elements based on the layout and page they are rendered on. ./media/bem~ish.png

Element CSS naming

Every element should have a specifically unique CSS name. No elements should be left without a class.

Do NOT do this:

<!-- not very descriptive of your intent. What are your dogs doing here? Why should I care if they are YOUR dogs?-->
<div className={classes.my_dogs}>
    <!-- THIS SPAN IS BAD AND DIFFICULT TO TARGET WITH CSS AND YOOU SHOULD FEEL BAD -->
    <span>
        <!-- ... just... why? ...WHY!? a ul serves the same function. just style the ul  -->
        <div>
            <!-- Cool, but COMPLETELY unrelated to the parent container. -->
            <!-- kittens/kitten This creates a TON of confusion and it often easy to overlook and hard to remember -->
            <ul className={classes.kittensBlender}>
                <!-- Why it is a blender? Does it need to be a blender? maybe a more apt name would be blendedKitten -->
                <!-- Also, "toys_1" Does NOT describe the INTENT of the list. we should be more SPECIFIC! -->
                {this.props.toys_1.map((item, i)=> <li className={classes.kitten}></li>}
            </ul>
        </div>
    </span>
</div>

Much better:

<!-- if the name of the component pa-->
<div className={classes.dogToys}>
    <!-- Title vs Header is debatable here. just pick one and BE CONSISTENT -->
    <h3 className={classes.dogToysTitle}>{props.title}</h3>
    <!-- If wrap an element within another div, just make sure there are at least TWO elements inside it-->
    <!-- In fact, we should consider wrappiing every TWO elements within a div to provide better style override opportinities -->
    <div className={classes.dogToysContainer}>
        <!-- don't switch up from Title to Header now. If you do, go back and change the other one to header.  -->
        <!-- You might be tempted to go with SubTitle here, but we are within the Container. -->
        <!-- If you want to move this next to to be a sibling of the dogToysTitle element, -->
        <!-- you would name it SubTitle and wrap both dogToysTitle and dogToysSubTitle in a dogToysTitleWrapper div. -->
        <p className={classes.dogToysContainerTitle}></p>
        <!-- dogToysChewToys vs dogToysChewToyList - always go with the List instead of pluralizing a shorter name. -->
        <!-- Remember, we want to be SPECIFIC! The name chosen based on the property we are maping over to generate the list -->
        <!-- that name should also be SPECIFIC to the intent. -->
        <ul className={classes.dogToysChewToyList}>
            <!-- dogToysChewToys vs dogToysChewToyList - always go with the List instead of pluralizing a shorter name. --> 
            <!-- Remember, we want to be specific! Theese are Dog Chew toys. -->
            <!-- The naming should be consistent so it's easy to find issues -->
            {this.props.dogChewToys.map((item, i)=> (
                <!-- dogToysChewToyListItem. This is a highly specific name. this shows intent, itration, specificity, -->
                <!-- and it is VERY easy to see what it is doing JUST by looking at the name -->
                <li key={title+i} className={classes.dogToysChewToyListItem}>{item}</li>
            ))}
        </ul>
    </div>
</div>

Full~ish example:

<!-- Wrapper - outer becomes .dog-toys-wrapper -->
<div className={classes.dogToysWrapper}>
    <!-- when unsure, Think of the intent, then fall back to the name of the element if need be.-->
    <!-- becomes .dog-toys-caption -->
    <caption className={classes.dogToysCaption}></caption>
    <!-- this will become .dog-toys-root. Why is the root inside a wrapper? It doesn't need to be. Just be consistent. -->
    <div className={classes.dogToys}>
        <!-- becomes .dog-toys-title -->
        <h3 className={classes.dogToysTitle}>{props.title}</h3>
        <!-- becomes .dog-toys-container -->
        <div className={classes.dogToysContainer}>
            <!-- becomes .dog-toys-container-title -->
            <p className={classes.dogToysContainerTitle}></p>
            <!-- becomes .dog-toys-chew-toy-list -->
            <ul className={classes.dogToysChewToyList}>
                <!-- becomes .dog-toys-chew-toy-list -->
                {this.props.dogChewToys.map((item, i)=> (
                    <!-- becomes .dog-toys-chew-toy-list-item -->
                    <li key={title+i} className={classes.dogToysChewToyListItem}>{item}</li>
                ))}
            </ul>
        </div>
    </div>
</div>

If you end up nesting containers within containers and wrappers within wrappers, etc...

STOP

Make a new component.

Breakpoints.

We have standardized the breakpoints to hit most popular device widths.

mediaBreakpoints: [375, 480, 640, 768, 1024, 1280, 1366]
  • 375 - 640: targets most Mobile devices. Some guides show 320, but those are older iphone 4s~5 era devices.
  • 640 - 1280 Targets most tablet devices and smaller laptop screens
  • 1366+ - Desktop Only

Local Development within in the content-portal repo

$ cd ~/src
$ git clone [email protected]:Jorsek/content-portal-themes.git
$ cd content-portal-themes 
$ npm link
$ cd ../content-portal 
& npm link @jorsek/content-portal-themes