Skip to content

Convert ICSS module exports to strongly typed TypeScript objects

License

Notifications You must be signed in to change notification settings

Brainshaker95/icss-to-ts

Repository files navigation

Contributors Forks Stargazers Issues MIT License

IcssToTs

Convert ICSS module exports to strongly typed TypeScript objects

☄️ Bug reports / feature requests »


Table Of Contents

   ⬆   

👋 About The Project

This project aims to provide a simple way of working with strongly typed objects that were exported from ICSS modules.

Given an ICSS module like this:

:export {
  foo: red;
  bar-baz: 255, 255, 255;
}

A TypeScript object conforming to this interface will be returned when using the string- and the RGB-parser respectively:

interface MyIcssVariables {
  readonly foo: string;
  readonly bar: {
    readonly baz: {
      readonly red: number;
      readonly green: number;
      readonly blue: number;
    },
  };
}

   ⬆   

🚀 Installation

Bun

bun add icss-to-ts

Yarn

yarn add icss-to-ts

PNPM

pnpm add icss-to-ts

NPM

npm i icss-to-ts

   ⬆   

👀 Usage

import icssToTs from 'icss-to-ts';
// or
import { icssToTs } from 'icss-to-ts';
/* ./path/to/icss-file.module.css */
:export {
  foo: red;
  bar-baz: 255, 255, 255;
}

/* ./path/to/icss-file.module.scss */
:export {
  foo: red;
  bar: {
    baz: 255, 255, 255;
  };
} 
import { icssToTs, parsers } from 'icss-to-ts';
import icssExports from './path/to/icss-file.module.css';
// import icssExports from './path/to/icss-file.module.scss';

const css = icssToTs(icssExports, {
  foo: parsers.asString,
  bar: {
    baz: parsers.asRgb,
  },
});

console.log(css);
/*
  {
    foo: 'red',
    bar: {
      baz: {
        red: 255,
        green: 255,
        blue: 255
      }
    }
  }
*/

   ⬆   

💻 API

🏠 Built-in Parsers

asString

Strips surrounding single or double quotes from the value if present.

asString('foo');     // -> 'foo'
asString('\'foo\''); // -> 'foo'
asString('"foo"');   // -> 'foo'

Note: All of the below parsers internally call to asString before further processing.

asNumber

Ensures that the given value is a finite number.

asNumber('0');        // -> 0
asNumber('"1"');      // -> 1
asNumber('\'1.21\''); // -> 1.21
asNumber('1px');      // -> throws
asNumber('Infinity'); // -> throws
asNumber('NaN');      // -> throws

asBoolean

Ensures that the given value is a representation of a boolean.

asBoolean('0');     // -> false
asBoolean('"1"');   // -> true
asBoolean('false'); // -> false
asBoolean('true');  // -> true
asBoolean('');      // -> throws
asBoolean('2');     // -> throws
asBoolean('foo');   // -> throws

asUnit

Extracts numbers from values with a specific unit.
Some unit parsers for the most common use cases are packaged with this library.

Note: Uses asNumber internally.

asPx('10px');     // -> 10
asRem('10rem');   // -> 10
asEm('10em');     // -> 10
asPercent('10%'); // -> 10
asVh('10vh');     // -> 10
asVw('10vw');     // -> 10
asDvh('10dvh');   // -> 10
asDvw('10dvw');   // -> 10
asPx('10pix');    // -> throws
asRem('10');      // -> throws

// You can simply construct your own unit parser like this:
asUnit('vmax')('50vmax'); // -> 50
asUnit('vmin')('50vmin'); // -> 50
asUnit('vmin')('50vmax'); // -> throws

asTuple

Parses a one-dimensional array from a space- and/or comma-separated list.

asTuple('0 1 2');       // -> ['0', '1', '2']
asTuple('0, 1, 2');     // -> ['0', '1', '2']
asTuple('0, 1 2');      // -> ['0', '1', '2']
asTuple('"0, 1, 2"');   // -> ['0', '1', '2']
asTuple('foo bar baz'); // -> ['foo', 'bar', 'baz']

asHex

Ensures that the given value is a valid hex color.
Two separate parsers are available: One for a string and one for a number representation.

asHexString('#E1E1E1');   // -> '#E1E1E1'
asHexNumber('#E1E1E1');   // -> 0x_E1_E1_E1
asHexNumber('E1E1E1');    // -> throws
asHexNumber('#E1E1E1E1'); // -> throws
asHexNumber('#FFFFFG');   // -> throws

asHexa

Ensures that the given value is a valid hexa color.
Two separate parsers are available: One for a string and one for a number representation.

asHexaString('#E1E1E1E1');   // -> '#E1E1E1E1'
asHexaNumber('#E1E1E1E1');   // -> 0x_E1_E1_E1_E1
asHexaNumber('E1E1E1E1');    // -> throws
asHexaNumber('#E1E1E1E1E1'); // -> throws
asHexaNumber('#FFFFFFFG');   // -> throws

asRgb

Parses an object confirming to the Rgb interface.

Note: Uses asNumber and asTuple internally.

asRgb('0 127 255');      // -> { red: 0, green: 127, blue: 255 }
asRgb('0, 127, 255');    // -> { red: 0, green: 127, blue: 255 }
asRgb('0, 127 255');     // -> { red: 0, green: 127, blue: 255 }
asRgb('0 127');          // -> throws
asRgb('-1 256 42');      // -> throws
asRgb('red green blue'); // -> throws

asRgba

Parses an object confirming to the Rgba interface.

Note: Uses asNumber and asTuple internally.

asRgba('0 127 255 1');          // -> { red: 0, green: 127, blue: 255, alpha: 1 }
asRgba('0, 127, 255 1');        // -> { red: 0, green: 127, blue: 255, alpha: 1 }
asRgba('0, 127 255 1');         // -> { red: 0, green: 127, blue: 255, alpha: 1 }
asRgba('0 127 255 2');          // -> throws
asRgba('0 127 255 -1');         // -> throws
asRgba('red green blue alpha'); // -> throws

🌲 Custom Parsers

If none of the built-in parsers satisfy your needs you can simply provide your own parser inside the schema.

Simple example of a parser for a tuple of numbers:

import { icssToTs, asNumber, asTuple } from 'icss-to-ts';
import icssExports from './path/to/icss-file.module.css';
/*
  :export {
    foo: 1 3.3 7;
  }
*/

const css = icssToTs(icssExports, {
  foo: (value: string): number[] => asTuple(value).map(asNumber),
});

console.log(css);
/*
  {
    foo: [1, 3.3, 7]
  }
*/

   ⬆   

❤️ Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!

  1. Fork the Project
  2. Create your Feature Branch => git checkout -b feature/my-new-feature
  3. Commit your Changes => git commit -m 'feat(my-new-feature): add some awesome new feature'
  4. Push to the Branch => git push origin feature/my-new-feature
  5. Open a Pull Request

   ⬆   

⭐ License

Distributed under the MIT License. See LICENSE for more information.

   ⬆   

🌐 Acknowledgments

   ⬆