Convert ICSS module exports to strongly typed TypeScript objects
☄️ Bug reports / feature requests »
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;
},
};
}
Bun
bun add icss-to-ts
Yarn
yarn add icss-to-ts
PNPM
pnpm add icss-to-ts
NPM
npm i icss-to-ts
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
}
}
}
*/
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.
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
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
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
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']
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
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
Parses an object confirming to the Rgb interface.
Note: Uses
asNumber
andasTuple
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
Parses an object confirming to the Rgba interface.
Note: Uses
asNumber
andasTuple
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
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]
}
*/
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!
- Fork the Project
- Create your Feature Branch =>
git checkout -b feature/my-new-feature
- Commit your Changes =>
git commit -m 'feat(my-new-feature): add some awesome new feature'
- Push to the Branch =>
git push origin feature/my-new-feature
- Open a Pull Request
Distributed under the MIT License. See LICENSE for more information.