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

bidi-css-js

v3.1.0

Published

Logical, flow-ralative conversion for CSS in JS objects

Downloads

2,445

Readme

bidi-css-js

Logical conversion of flow-relative properties and values for CSS in JS objects

Build Status Code Coverage Dependencies version

MIT License All Contributors

The problem

With properties and value containing a physical direction, e.g., margin-left or float: right, CSS has traditionally been planned and authored to accommodate for a single-direction flow of content - either from left to right, or from right to left. Reality, however, often requires that we author our styles in a manner that can easily be applied independently of the document or component flow-direction.

CSS seems to now slowly starting to progress in the right direction, towards allowing the authoring of flow-realtive styles. Flexbox got this right with justify-content, align-items, etc., and an initial CSSWG proposal to address the issue is in place. The most basic of features, such as text-align: start are already supported in some browsers and others, such as margin-start, have some prefixed support. Most of the proposed features, however, are not currently implemented in any browser support.

This solution

This library aims to provide a way to easily author styles, (mostly) in line with the CSSWG proposal (and expand on it a little bit), while still ensuring backwards compatibility with the way thing were done before.

It is built using the core logic provided by Kent C. Dodds's rtl-css-js, and is basically just a thin layer around it providing different behavior.

It is a function with accepts two arguments: a CSS-in-JS object, and a string indicating the flow-direction according to which the styles object will be parsed.

It will convert, for instance, paddingStart to either paddingLeft or paddingRight, as well as all other properties where it makes sense to do so, depending on the provided flowDirection

Not a polyfill

It is important to note that this package is not a true polyfill for the proposal, as all start and end properties (and so on) are converted to left or right values (etc.), and will not automatically flip when the flow direction of the element, inherited or otherwise is changes in by the html dir attribute or the direction css property.

Four directional shorthand properties

The proposal alters the way values for four-directional shorthand properties (padding, margin, etc.) are written when using the logical keyword.

The values of four-directional shorthand properties, without the logical keyword are written clock-wise: top, right, bottom and left. While in ltr mode, that would translate to block-start, inline-end, block-end and inline-start. However, under the new spec, when the logical keyword is used, values order is interpreted as block-start, inline-start, block-end and inline-end.

Earlier versions of this library got this wrong, and it was corrected in version 2.0.0

Installation

This module is distributed via npm which is bundled with node and should be installed as one of your project's dependencies:

yarn add bidi-css-js
# or
npm install --save bidi-css-js

Usage

This library exposes a CommonJS, as well as an ES Module and UMD with a bidiCSSJS global.

// If using CommonJS
const bidiCSSJS = require('bidi-css-js') 

// If using ES Modules
import bidiCSSJS from 'bidi-css-js/bidi-css-js.esm' 
const styles = bidiCSSJS({paddingStart: 23}, 'rtl')
console.log(styles) // logs {paddingRight: 23}

You can also just include a script tag in your browser and use the bidiCSSJS variable:

<script src="https://unpkg.com/bidi-css-js"></script>
<script>
  const styles = bidiCSSJS({paddingStart: 23}, 'rtl')
  console.log(styles) // logs {paddingRight: 23}
</script>

Logical properties and values

This library is intended to mimic the implementation suggested in the CSSWG's Logical Properties and Values Level 1 proposal, with some minor additional sugar. It only covers the inline-flow (e.g., left<->right) aspects of the proposal and not its block-flow (e.g. top<->bottom) aspects.

Flow-relative properties:

Longhand properties

| Property | LTR Value | RTL Value | Notes | |-|-|-|-| | paddingStart | paddingLeft | paddingRight | | | paddingEnd | paddingRight | paddingLeft | | | marginStart | marginLeft | marginRight | | | marginEnd | marginRight | marginLeft | | | paddingInlineStart | paddingLeft | paddingRight | | | paddingInlineEnd | paddingRight | paddingLeft | | | marginInlineStart | marginLeft | marginRight | | | marginInlineEnd | marginRight | marginLeft | | | insetInlineStart | left | right | | | insetInlineEnd | right | left | | | start | left | right | This property is not part of the official spec and only included for convinience because insetInlineStart is so cumbersome. If youd like to keep 100% compatibility with the spec, avoid usind this property** | | end|right|left| **This property is not part of the official spec and only included for convinience becauseinsetInlineEnd is so cumbersome. If youd like to keep 100% compatibility with the spec, avoid usind this property | | borderStart | borderLeft | borderRight | -- | | borderEnd | borderRight | borderLeft | -- | | borderStartColor | borderLeftColor | borderRightColor | -- | | borderEndColor | borderRightColor | borderLeftColor | -- | | borderStartStyle | borderLeftStyle | borderRightStyle | -- | | borderEndStyle | borderRightStyle | borderLeftStyle | -- | | borderStartWidth | borderLeftWidth | borderRightWidth | -- | | borderEndWidth | borderRightWidth | borderLeftWidth | -- | | borderInlineStart | borderLeft | borderRight | -- | | borderInlineEnd | borderRight | borderLeft | -- | | borderInlineStartColor | borderLeftColor | borderRightColor | -- | | borderInlineEndColor | borderRightColor | borderLeftColor | -- | | borderInlineStartStyle | borderLeftStyle | borderRightStyle | -- | | borderInlineEndStyle | borderRightStyle | borderLeftStyle | -- | | borderInlineStartWidth | borderLeftWidth | borderRightWidth | -- | | borderInlineEndWidth | borderRightWidth | borderLeftWidth | -- | | borderTopStartRadius | borderTopLeftRadius | borderTopRightRadius | This property is, at the moment, missing from the spec, but is expected to be defined at a later stage. See w3c/csswg-drafts#491 | | borderTopEndRadius | borderTopRightRadius | borderTopLeftRadius | This property is, at the moment, missing from the spec, but is expected to be defined at a later stage. See w3c/csswg-drafts#491 | | borderBottomStartRadius | borderBottomLeftRadius | borderBottomRightRadius | This property is, at the moment, missing from the spec, but is expected to be defined at a later stage. See w3c/csswg-drafts#491 | | borderBottomEndRadius | borderBottomRightRadius | borderBottomLeftRadius | This property is, at the moment, missing from the spec, but is expected to be defined at a later stage. See w3c/csswg-drafts#491 | | borderStartStartRadius | borderTopLeftRadius | borderTopRightRadius || This property is, at the moment, missing from the spec, but is expected to be defined at a later stage. See w3c/csswg-drafts#491 | -- | | borderStartEndRadius | borderTopRightRadius | borderTopLeftRadius | This property is, at the moment, missing from the spec, but is expected to be defined at a later stage. See w3c/csswg-drafts#491 | | borderEndStartRadius | borderBottomLeftRadius | borderBottomRightRadius | This property is, at the moment, missing from the spec, but is expected to be defined at a later stage. See w3c/csswg-drafts#491 | | borderEndEndRadius | borderBottomRightRadius | borderBottomLeftRadius | This property is, at the moment, missing from the spec, but is expected to be defined at a later stage. See w3c/csswg-drafts#491 |

Shorthand properties

From the spec: The shorthand properties for margin, padding, and border set values for physical properties by default. But authors can specify the logical keyword at the beginning of the property value to indicate that the values map to the flow-relative properties instead of the physical ones. The following [CSS21] shorthand properties [ ... ] accept the logical keyword: margin, padding, border-width, border-style, border-color. [ ... ] When the logical keyword is present in the value, the values that follow are assigned to the flow-relative properties as follows:

  • If only one value is set, the value applies to all four flow-relative longhands.
  • If two values are set, the first is for block-start and block-end, the second is for inline-start and inline-end.
  • If three values are set, the first is for block-start, the second is for inline-start and inline-end, and the third is for block-end.
  • If four values are set, they apply to the block-start, inline-start, block-end, and inline-end sides in that order.

Example:

bidiCSSJS({
  margin: 'logical 0 10px 0 20px'
}, 'rtl'); // => { margin: '0 10px 0 20px' }
bidiCSSJS({
  margin: 'logical 0 10px 0 20px'
}, 'ltr'); // => { margin: '0 20px 0 10px' }

For convinience, the library also transforms the following properties in a similar manner, although they are not included in the spec:

| Property | Example | LTR Value | RTL Value | Notes | |-|-|-|-|-| | backgroundImage | logical url(/foo/bar-ets.png) | url(/foo/bar-rtl.png) | url(/foo/bar-ltr.png)| ets is short for end-to-start; ste is short for start-to-end | | backgroundImage | logical linear-gradient(to start top, blue, red) | logical linear-gradient(to left top, blue, red) | logical linear-gradient(to right top, blue, red) | | | backgroundImage | logical repeating-linear-gradient(to start, #00ff00 0%, #ff0000 100%) | logical repeating-linear-gradient(to left, #00ff00 0%, #ff0000 100%) | logical repeating-linear-gradient(to right, #00ff00 0%, #ff0000 100%) | | | backgroundPosition | logical start top | left top | right top | -- | | backgroundPosition | logical 77% 40% | 77% 40% | 23% 40% | -- | | backgroundPositionX | See backgroundPosition | | background | See backgroundImage and backgroundPosition | | borderRadius | logical 1px 2px 3px 4px | 1px 2px 3px 4px | 2px 1px 4px 3px | Will hopefuly be included at a later stage. See w3c/csswg-drafts#1776 | | borderRadius | logical 1px 2px 3px 4px / 5px 6px 7px 8px | 1px 2px 3px 4px / 5px 6px 7px 8px | 2px 1px 4px 3px / 6px 5px 8px 7px | Will hopefuly be included at a later stage. See w3c/csswg-drafts#1776 | | boxShadow | logical -1px 2px 3px 3px red | -1px 2px 3px 3px red | 1px 2px 3px 3px red || | boxShadow | logical inset 1px 2px 3px 3px red | inset 1px 2px 3px 3px red | inset -1px 2px 3px 3px red || | mozBoxShadow | See boxShadow | -- | -- | -- | | webkitBoxShadow | See boxShadow | -- | -- | -- | | textShadow | logical red -2px 0 | red -2px 0 | red 2px 0 | -- | | textShadow | logical -2px 0 red | -2px 0 red | 2px 0 red | -- | | transform | logical translate(30%) | translate(30%) | translate(-30%) | Currently only operates on translate[X] | | transform | logical translateX(30%) | translateX(30%) | translateX(-30%) | Currently only operates on translate[X] | | transform | logical translate(30%, 20%) | traslate(30%, 20%) | translate(-30%, 20%) | Currently only operates on translate[X|3d] | | transform | logical translateY(30px) rotate(20deg) translateX(10px) | translateY(30px) rotate(20deg) translateX(10px) | translateY(30px) rotate(20deg) translateX(-10px) | Currently only operates on translate[X|3d] | | transform | logical translate3d(30%, 20%, 10%) | translate3d(30%, 20%, 10%) | translate3d(-30%, 20%, 10%) | Currently only operates on translate[X] | | mozTransform | See transform | -- | -- | -- | | webkitTransform | See transform | -- | -- | -- | | transformOrigin | logical start top | left top | right top | -- | | transformOrigin | logical 77% 40% | 77% 40% | 23% 40% | -- | | mozTransformOrigin | logical start top | left top | right top | -- | | mozTransformOrigin | logical 77% 40% | 77% 40% | 23% 40% | -- | | webkitTransformOrigin | logical start top | left top | right top | -- | | webkitTransformOrigin | logical 77% 40% | 77% 40% | 23% 40% | -- |

Flow-relative values:

In properties that do not accept the logical keword , values containing the following keywords will be automatically transformed. This is not 100% spec complient.

| Value | LTR Value | RTL Value | Notes | |-|-|-|-| | 'ste' | 'ltr' | 'rtl' | Not part of the official spec | | 'ets' | 'rtl' | 'ltr' | Not part of the official spec | | 'inline-start' | 'left' | 'right' | | 'inline-end' | 'right' | 'left' | | 'start' | 'left' | 'right' | | 'end' | 'right' | 'left' | | 'start-resize' | 'w-resize' | 'e-resize' | Not part of the spec | | 'end-resize' | 'e-resize' | 'w-resize' | Not part of the spec | | 'bottomstart-resize' | 'sw-resize' | 'se-resize' | Not part of the spec | | 'bottomend-resize' | 'se-resize' | 'sw-resize' | Not part of the spec | | 'topstart-resize' | 'nw-resize' | 'ne-resize' | Not part of the spec | | 'topend-resize' | 'ne-resize' | 'nw-resize' | Not part of the spec |

Caveats

Same as rtl-css-js:

This library falls short of a polyfill, and does not accommodate for dynamic changes in the flow direction. See here

While not actually a real caveat, it is worth noting that the proposal changes the way four-directional shorthand properties are evaluated. see here

background

Right now background and backgroundImage just replace all instances of ltr with rtl and right with left. This is so you can have a different image for your LTR and RTL, and in order to flip linear gradients. Note that this is case sensitive! Must be lower case. Note also that it will not change bright to bleft. It's a little smarter than that. But this is definitely something to consider with your URLs.

Thanks

Kent C. Dodds and all other contributors to rtl-css-js. As mentioned above, this library is not much more than a thin wrapper around it's core logic.

Contributors

Thanks goes to these people (emoji key):

| Jonathan Pollak💻 📖 ⚠️ | | :---: |

This project follows the all-contributors specification. Contributions of any kind welcome!

LICENSE

MIT