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 🙏

© 2025 – Pkg Stats / Ryan Hefner

highstyle

v0.2.6

Published

A toolkit for fast and flexible manipulation of inline styles

Downloads

6

Readme

HighStyle

A toolkit for fast and flexible manipulation of inline styles using composable transformations.

npm install --save highstyle

Overview

HighStyle is a collection of utility functions for working with 'CSS in JS' style objects as simply as any other JS objects.

Specifically, these utilities smooth over the difficulties of working with CSS shorthand properties, as well as numeric properties provided as strings, which together cause numerous problems when working with style objects.

// given the provided style object:
// style = { margin: 20, fontSize: '16px' }

// returns undefined, not 20
style.marginTop;

// returns NaN, not 24
style.fontSize * 1.5

Inspired by higher-order components, all HighStyle utilities are (parameterised) transforms - pure functions which take one style object and return another. This allows them to be easily composed together, as well as memoized for efficiency.

transform(...args) = (style => style)

TOC

Manipulating specific CSS properties

highstyle.filter(...properties: string[]): (style => style)

Filter and return specific style properties.

highstyle.filter('width', 'marginTop')({ width: 100, height: 50, margin: 20 });

// returns { width: 100, marginTop: 20 }

highstyle.expandFor(...properties: string[]): (style => style)

Expand relevant shorthands to access the given properties.

highstyle.expandFor('marginTop')({ width: 100, margin: 20 });

// returns { width: 100, marginTop: 20, marginRight: 20, marginBottom: 20, marginLeft: 20 }

highstyle.numeric(...properties: string[]): (style => style)

Ensure the given properties are in numeric form (or 0 if undefined).

highstyle.numeric('width', 'marginTop')({ margin: '20px' });

// returns { width: 0, marginTop: 20, marginRight: '20px', marginBottom: '20px', marginLeft: '20px' }

Merging together style objects

highstyle.merge(...styles: Object[]): (style => style)

Merge in the given list of styles from left-to-right.

highstyle.merge({ margin: 20 }, { width: 100, marginRight: 30 })({ marginTop: 10 });

// returns { width: 100, marginTop: 20, marginRight: 30, marginBottom: 20, marginLeft: 20 }

highstyle.defaults(...styles: Object[]): (style => style)

Use the given defaults for undefined styles, merged in left-to-right.

highstyle.defaults({ width: 100, margin: 10 })({ marginTop: 20 });

// returns { width: 100, marginTop: 20, marginRight: 10, marginBottom: 10, marginLeft: 10 }

Working with nested styles

Roughly equivalent to CSS pseudo-classes, HighStyle can work with nested styles.

const style = {
  fontSize: 16,
  focus: {
    fontWeight: 'bold',
  },
  hover: {
    color: 'red',
    focus: {
      fontWeight: '900',
    },
  },
}

highstyle.mergeKeys(...keys: string[] | [{ [key]: boolean }]): (style => style)

Merge in the modifiers for the given keys, with deeper nested modifiers taking higher priority.

If the keys are provided as an object, those with truthy values will be used.

highstyle.mergeKeys('focus', 'hover')(style);

// returns { fontSize: 16, fontWeight: '900', color: 'yellow' }
highstyle.mergeKeys({ focus: true, hover: false })(style);

// returns { fontSize: 16, fontWeight: 'bold', hover: { color: 'red', fontWeight: '900' } }

highstyle.filterKeys(...keys: string[]): (style => style)

Filter and return only the nested styles for the given keys.

highstyle.filterKeys('hover')(style);

// returns { fontSize: 16, hover: { color: 'red' } }

mapStyle() - React higher-order component helper

HighStyle also comes with a higher-order component mapStyle to simplify using the above utilities to build complex React components which manipulate their provided inline styles.

This HOC allows for using the standard React style prop to hold individual or multiple styles, which are transformed according to the provided transforms.

// single
props.style = {
  fontSize: 16,
  margin: '10px 20px',
  ...
}

// multi
props.style = {
  text: {
    fontSize: 16,
  },
  panel: {
    background: '#ddd',
  },
  ...
}

The HOC accepts a single parameter mapPropsToTransforms, which has one of three forms depending on the shape of the style prop. For the second and third forms, the new styles are combined with the existing ones, overwriting only when the keys are the same.

// basic (maps single => single)
mapStyle(
  mapPropsToTransforms: (props) => (style => style)[]
): HigherOrderComponent

// split (maps single => multi)
mapStyle(
  mapPropsToTransforms: (props) => { [newKey]: (style => style)[] }
): HigherOrderComponent

// multi (maps multi => multi)
mapStyle(
  mapPropsToTransforms: (props) => { [baseKey]: { [newKey]: (style => style)[] } }
): HigherOrderComponent

Example 1

Here we use the basic mapStyle api to create a component ShortText which forces its contents to be red whenever they exceed 20 characters, along with a default fontFamily of Verdana.

import highstyle, { mapStyle } from 'highstyle';

const ShortText = mapStyle(
  ({ children }) => [
    highstyle.defaults({ fontFamily: 'Verdana' }),
    highstyle.merge({ color: children.length > 20 ? 'red' }),
  ],
)('p');

// This will be blue
<ShortText style={{ color: 'blue' }} >Hello World!</ShortText>

// This will be red
<ShortText style={{ color: 'blue' }} >Hello World! Hello World!</ShortText>

Example 2

Here we combine HighStyle with Recompose to create a HOC addHover which applies the nested hover style when the wrapped component is hovered.

import highstyle, { mapStyle } from 'highstyle';
import { compose, withState } from 'recompose';

const addHover = compose(
  withState('hovered', 'setHovered', false),
  withHandlers({
    onMouseMove: ({ setHovered }) => () => setHovered(true),
    onMouseLeave: ({ setHovered }) => () => setHovered(false),
  }),
  mapStyle(({ hovered }) => [
    highstyle.mergeKeys('hover'),
  ]),
);

const Link = addHover('a');

// This will be red when hovered over
<Link href="#" style={{ hover: { color: 'red' } }}>Click me!</Link>