This package has been deprecated

Author message:

Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

@missionx-co/twstyle
TypeScript icon, indicating that this package has built-in type declarations

1.0.5 • Public • Published

Tailinwd Styling Object

As its name denotes, Tailwind Styling Object is a styling object leverages the power of TailwindCSS providing the ability to use its utilities as key-value JS object.

Intuition

UI kit and frameworks are making the life a lot easier for frontend developers. However, one of the main concerns when implementing them is the ability and the readiness of style customization so that they match the developers needs.

In another side, TailwindCSS usage is growing day by day because of its big advantages. So if UI kit was chosen to be implemented using TailwindCSS, the main challenge will be make it easily Customizable with avoiding the conflicts between TailwindCSS utilities, wherefore the Tailwind Styling Object was created.

First Glance

As mentioned previously, Tailwind Styling Object enables the user to apply TailwindCSS classes as key-value pairs inside JS object. Where the object properties are TailwindCSS configured plugin names and the values are the classes that each plugin generates.

For example, the backgroundColor plugin generates the bg-{color} classes and accordingly the value of it will be one of bg-white, bg-gray-100….etc

const twStyle: TailwindStylingObject = {
  backgroundColor: 'bg-white',
  borderColor: 'border-gray-400',
  focus: {
    borderColor: 'focus:border-blue-500',
  },
  responsive: {
    sm: { width: 'sm:w-1' },
  },
};

Some properties like padding takes an array as a value because a Dom element can take several padding classes

const twStyle: TailwindStylingObject = {
  padding: ['px-2', 'py-1'],
};

Why

Extracting Components and avoiding conflicts

To better explain this. let’s go with an example.Imagine having a pre-styled Button component, with aclassNamea property to allow for style customization

const Button = ({ className, children }) => (
  <button className={`bg-red-500 ${className}`}>{children}</button>
);

When user wants to change the button background color, she will pass the new background class through the className property

<Button className="bg-red-600">Click Me</Button>

With the combination above the result DOM element will be

<button class="bg-red-500 bg-red-600">Click Me<button>

Can you see the problem?. At the end, we had a DOM element that has two classes related to the same css property and we might have a conflict here.

Using TailwindStylingObject will eliminate such a problem.

The component

import twStyleToClassName from '@missionx-co/twstyle';

const defaultTwStyle = {
  backgroundColor: 'bg-red-500',
};

const Button = ({ twStyle, children }) => (
  <button className={twStyleToClassName(defaultTwStyle, twStyle)}>
    {children}
  </button>
);

The usage

const style={
    backgroundColor: 'bg-red-600'
}

<Button twStyle={style}>
    Click Me
</Button>

The result DOM element

The twStyleToClassName function will detect the duplicate styling and will prioritize the user defined styling (The second parameter of the function).Then it will convert the resulted object into the proper class name so it can be passed to the DOM element.

<button class="bg-red-600">Click Me</button>

Readability:

Although that readability is not a problem for me personally but I’ve seen a lot of people complaining about classes readability.

Tailwind styling object will solve the issue of readability since that all the classes will be converted into a key/value javascript object.

const twStyle = {
    padding: ['px-3', 'py-2'],
    border: ['border'],
    borderRadius: ['rounded-md'],
    fontSize: 'text-sm',
    color: 'text-white',
    backgroundColor: 'bg-red-500',
    borderColor: 'border-red-500',
    boxShadow: 'shadow-md',
    hover: {
        backgroundColor: 'hover:bg-red-600',
        borderColor: 'hover:border-red-600'
    },
    focus: {
        backgroundColor: 'focus:bg-red-600',
        borderColor: 'focus:border-red-600',
        ringColor: 'focus:ring-red-300',
        ....
    }
}

Installation

Use npm or yarn to install this package as follows:

npm install --save @missionx-co/twstyle

or

yarn add @missionx-co/twstyle

Surely TailwindCSS must be installed and configured, You can follow this link to go through its installation Tailwindcss installation.

In addition, Typescript should be installed to utilize the types that Tailwind Styling Object provides.

Usage

Type Generation

After installation and initializing Tailwind config file,TailwindStylingObject typescript types files should be generated.

The generation could be done using the following command:

node node_modules/missionx/twstyle/dist/generate --outdir = "/src"

This command accepts outdir parameter which is used to set the output directory for the generated file. Typically, this folder would be the src folder in your project.

The above command should be executed from the directory at where tailwind.config.js is located (or its directory).

The output directory will a set of named typing files each of them represents a single Tailwindcss plugin.

In additon, it has a main index file which contains the TailwindStylingObject interface defintion:

import Space from './Space';
import DivideWidth from './DivideWidth';
.
.
.
import TransitionDelay from './TransitionDelay';
import Animation from './Animation';

export default interface TailwindStylingObject {
    ...
    backgroundAttachment ?: BackgroundAttachment;
    ...
    hover ?: {
        backgroundAttachment ?: `hover:${BackgroundAttachment}`;
        ...
    },
    ...
    responsive ?: {
        sm ?: {
            backgroundAttachment ?: `sm:${BackgroundAttachment}`;
            hover ?: {
                backgroundAttachment ?: `sm:${`hover:${BackgroundAttachment}`}`;
                ...
            }
        ...
        },
        ...
    },
    ...
}

As hinted above, TailwindCSS utilities with their variants (as configured in config file) are represented in TS interface according to the following algorithm.

Usage notes

  • Due to the new TailwindCSS JIT compiler it’s impossible to detect all the nested variants, accordingly, the generation command will generate a TS file with only one level of variants nesting for all the known variants excepts for dark and the responsive variants.

  • Normal utilities represented as optional properties has the type of union between the available classes

// `BackgroundAttachment.ts` file

type BackgroundAttachment = "bg-fixed" | "bg-local" | "bg-scroll";

// `index.ts` file

import BackgroundAttachment from './BackgroundAttachment';

export default interface TailwindStylingObject {
    ...
    backgroundAttachment ?: BackgroundAttachment;
    ...
}
  • Variants (except responsive and dark) are represented as object properties containing all the available utilities as properties.

  • responsive variant are represented as object property containing each of its defined breakpoints as first layer properties.

    Each property contains as properties all the utilities (and their variants) that supports responsive variant. These properties are defined in the same way as normal utilities and variants except that their values are prefixed with the breakpoint prefix.

      responsive ?: {
        ...
         sm ?: {
              backgroundAttachment ?: `sm:${BackgroundAttachment}`;
              hover ?: {
                  backgroundAttachment ?: `sm:${`hover:${BackgroundAttachment}`}`;
                  ...
              }
             }
         md ?: {...},
         lg ?: {...},
         ...
     }

Contributors:

  • Mahmoud Kassah
  • Mohammed Manssour

Readme

Keywords

none

Package Sidebar

Install

npm i @missionx-co/twstyle

Weekly Downloads

1

Version

1.0.5

License

MIT

Unpacked Size

76.2 kB

Total Files

41

Last publish

Collaborators

  • mohammed.manssour