Skip to content

Commit

Permalink
Release 2.0.0: Major Update with Enhanced Extensibility and Improved …
Browse files Browse the repository at this point in the history
…Typing (#45)

* chore: update biome config

* chore: biome tracks configs written in JS

* chore: update jest config

* chore: update Rollup and TS configs

* feat: Major refactoring of Colorus.js

- Refactored file structure for improved organization and maintainability.
- Added support for custom parsers, allowing users to create and integrate their own color models.
- Enhanced TypeScript definitions for better type safety and developer experience.
- Streamlined core methods to include only essential getters: luminance, rgb, hsl, hsv, cmyk, alpha, hue, along with source and error properties.
- Introduced built-in plugins for common transformations: invert, lighten, darken, saturate, desaturate, toCmyk, toHex, toHsl, toHsv, toRgb.
- Achieved 100% test coverage with new Jest tests, ensuring reliability and stability of the library.

This refactor improves usability, extensibility, and performance while maintaining strong type safety.

* docs: Add docs for working w/ parsers and plugins

- Introduced sections detailing the creation and usage of custom parsers with the dye() function.
- Included examples for the HSL and HEX parsers, showcasing color parsing and transformation.
- Provided best practices for regex and extract functions, emphasizing clarity and valid RGB output.
- Added tips for maintaining consistency in color channel extraction and serialization.

* fix(ColorParser): reset `lastIndex` in each call

- Removed `y` flag from regex expressions to prevent unintended lastIndex behavior across multiple matches.
- Added a reset of `lastIndex` in the ColorParser class to ensure consistent regex execution and prevent zeroed outputs on repeated calls with identical inputs.

* test: refactor Jest tests for `toCmyk`, `toHsl`, `toHsv`, `toRgb`, and `dye` modules

- Updated tests to include validation for potential lastIndex-related issues in regex-based operations.
- Ensured consistent behavior across multiple calls with identical inputs to prevent regression.

* chore: update build and test configs

* docs: update README.md

* docs(README): improve overall structure & headings

* docs(guide): improve parsers & plugins guide

* chore(tsconfig): should report unused variables

* chore(biome): should report unused imports and variables

* fix(linter): fix reported errors by new linter rules

* docs(CONTRIBUTING): update guide

* chore(package.json): bump version to 2.0.0

* fix(plugins/invert): should pass options to new plugin instance

* feat: Implement efficient hex to RGB conversion

- Replaced the old method of converting hex color strings to RGB with a new approach that utilizes a single call to Number.parseInt().
- The new method improves performance significantly, reducing the average conversion time from 228.3 ns to 82.6 ns, making it 2.77x faster.
- The function now extracts RGB and alpha values using bitwise operations, enhancing efficiency and maintaining clarity.
- Added input validation to ensure hex strings are in the correct format (6 or 8 characters).
- Removed hexToInt() utility since it's not required anymore.

This change is crucial for improving the performance of color processing in the application.

* refact(validation): remove unused validation utils

* refact(types): refact the plugins options and params

* docs(parsers): fix codeblock examples

* docs: upload initial API reference

* docs: reference API docs at the README and more
  • Loading branch information
supitsdu authored Nov 4, 2024
1 parent 4316ce0 commit 720ed03
Show file tree
Hide file tree
Showing 117 changed files with 3,692 additions and 3,305 deletions.
49 changes: 20 additions & 29 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,37 @@
# Contributing to Colorus.js 🎉

We welcome contributions to Colorus.js! Whether you're fixing bugs 🐛, improving documentation 📚, or adding new features through plugins ✨, your help is valuable in making this library even better.
Thank you for considering a contribution to **Colorus.js**! From fixing bugs to improving documentation or expanding functionality with plugins and parsers, every contribution is valuable.

## Future Plans: Mono-repo 📦
## Design Choice

In the future, we intend to transition the Colorus.js repository into a mono-repo structure. This will allow us to manage the core package and official plugins within a single repository, streamlining development and maintenance.
The design choice ensures that colors are parsed, transformed, and returned in predictable and reliable ways, even if it means some operations may be slower than highly optimized alternatives.

## Core Functionality: Non-Extensible (Intentional) 🔒
Despite this focus, **Colorus.js** performs efficiently in most use cases. While the library might not aim to be the absolute fastest, it’s still capable of handling high-demand operations quickly. If you identify areas where optimizations can be made without sacrificing validation, please feel free to propose changes or submit a pull request.

| Core Functionality | Extensible via Plugins |
| -------------------------- | ---------------------- |
| Color creation (`dye`) | No |
| Color conversions | No |
| Color adjustments | No |
| Accessibility calculations | No |
## Core and Extensible Features 🔒

The plugin system provides a powerful and flexible mechanism for adding custom features and behaviors to color objects created by `dye`. We encourage you to leverage this system to enhance the capabilities of Colorus.js without modifying its core. 💪
| Feature | Extensible via Plugins or Parsers |
| --------------------------------- | --------------------------------------------- |
| Color creation (`dye`) | [Parsers](docs/guide/WORKING_WITH_PARSERS.md) |
| Color conversions and adjustments | [Plugins](docs/guide/WORKING_WITH_PLUGINS.md) |

## Focus on Performance 🚀

We're always looking for ways to improve the performance of Colorus.js. Contributions that enhance the speed or reduce the bundle size of the library are highly appreciated. If you have ideas for optimizations or performance improvements, please share them with us!
The plugin and parser systems in version 2.0.0 allow easy extensibility, making it possible to add custom features while preserving the core library’s structure.

## How to Contribute 🛠️

1. **For complex or significant changes:** Please open an issue first to discuss your proposed changes with the maintainers. This helps ensure alignment with the project's goals and avoids potential conflicts or wasted effort. 💬

2. **For simple fixes (e.g., typos, grammar):** Feel free to directly open a pull request. 👍

3. In either case, follow these steps:
- Fork the repository and create a new branch for your feature or bug fix. 🍴
- Make your changes and ensure that the code is well-documented and tested. 🧪
- Submit a pull request, clearly describing your changes and their benefits. 🚀
1. **Significant Changes:** Open an issue first to discuss.
2. **Minor Fixes (e.g., typos):** Open a pull request directly.
3. **Steps:**
- Fork the repository, create a branch, and make your changes.
- Ensure documentation and tests accompany your updates.
- Submit a pull request with a clear, concise description.

## Documentation and Type Support 📚

Clear and comprehensive documentation is essential for any library, and Colorus.js is no exception. We strive to provide accurate and up-to-date documentation for all core functions, types, and the plugin system. Contributions that improve the documentation, add examples, or clarify usage are highly valued.
✍️

### Type Safety and Function Chaining 🔒⛓️
Complete documentation and robust TypeScript support are priorities for **Colorus.js**. Contributions that improve docs, examples, or types are always welcome.

We place a strong emphasis on type safety. The function chaining mechanism, in particular, relies heavily on TypeScript's type inference to provide a smooth and error-free developer experience. When contributing, pay close attention to maintaining and enhancing the type definitions, especially when modifying or adding new features that interact with the chaining mechanism.
## Type Safety and Chaining 🔒⛓️

We appreciate your interest in contributing to Colorus.js! Please don't hesitate to reach out if you have any questions or need further guidance. 🙌
Type safety is critical to **Colorus.js**, particularly in the chaining API. Please ensure typings are preserved or improved when contributing any functions affecting chaining behavior.

**Thank you for your support!** 🙏
**Thank you for supporting Colorus.js!** 🙏
77 changes: 41 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,60 +1,65 @@
<p align="center">
<img src="https://raw.githubusercontent.com/supitsdu/colorus-js/main/favicon.svg" width="256">
<p>

# Colorus.js

[![NPM](https://img.shields.io/badge/NPM-%23CB3837.svg?style=for-the-badge&logo=npm&logoColor=white&labelColor=black&color=black)](https://www.npmjs.com/package/colorus-js)
[![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white&labelColor=black&color=black)](https://www.typescriptlang.org/)
[![GitHub stars](https://img.shields.io/github/stars/supitsdu/colorus-js?style=for-the-badge&logo=Github&logoColor=white&labelColor=black&color=black)](https://github.com/supitsdu/colorus-js)

A versatile and powerful color manipulation library for JavaScript.
**Colorus.js** is a flexible color manipulation library with multi-format support and TypeScript compatibility.

## Features

- **Intuitive API:** Work with colors effortlessly using a simple and expressive function-based API.
- **Multiple Color Models:** Supports various color models, including RGB, HSL, HSV, and CMYK.
- **Flexible Input/Output:** Accepts color inputs in different formats (hex, rgb, hsl, etc.) and provides various output options.
- **Color Conversions:** Easily convert between different color models and formats.
- **Color Adjustments:** Perform common color adjustments like lightening, darkening, saturating, desaturating, and more.
- **Accessibility:** Calculate relative luminance and contrast ratios for improved accessibility.
- **Extensible:** Extend the core functionality with custom plugins.
- **TypeScript Support:** Provides full TypeScript support for enhanced type safety and developer experience.
- 🌈 **Model-Agnostic Design** – Supports HEX, RGB, HSL, HSV, CMYK, and is extendable to any color model.
- ⚡️ **Effortless Chaining** – Chain transformations with seamless TypeScript support for clarity and reliability.
- 🧩 **Extensible by Design** – Add custom parsers and plugins to unlock new models and functions.
- 🔒 **Solid Type Safety** – Robust TypeScript types deliver consistent, predictable color transformations.

### Usage
## Quick Start

```javascript
import { dye } from "colorus-js"

const color = dye("#ff0000") // Create a color from a hex code
const color = dye("rgb(255 0 0)")

console.log(color.hsl) // { h: 0, s: 100, l: 50, a: 1 }
console.log(color.luminance) // 0.21
console.log(color.source.isValid) // true
console.log(color.source.model) // "rgb"
```

### Multi-Format Support

```javascript
import { dye, hslParser } from "colorus-js"

console.log(color.rgb) // Output: { r: 255, g: 0, b: 0, a: 1 }
console.log(color.toHsl()) // Output: hsl(0, 100%, 50%)
const color = dye("hsl(120deg 50% 30%)", { parsers: [hslParser] })

const lighterColor = color.lighten(0.2) // Lighten the color by 20%
console.log(lighterColor.toHex()) // Output: #ff6666
console.log(color.luminance) // 0.13
console.log(color.rgb) // { r: 38.25, g: 114.75, b: 38.25, a: 1 }
```

### Plugins
**Built-in Parsers:** `cmykParser`, `hexParser`, `hslParser`, `hsvParser`, `rgbParser` (default)

Extend the `dye` function with custom methods using plugins.
### Custom Plugins

```javascript
const colorWithPlugin = dye("#0000ff", {
plugins: {
isBlue() {
return this.rgb.b > 200
}
}
import { createPlugin, dye } from "colorus-js"

// Custom grayscale plugin definition
const grayscale = createPlugin("grayscale", function () {
const avg = (this.rgb.r + this.rgb.g + this.rgb.b) / 3
return dye({ r: avg, g: avg, b: avg, a: this.rgb.a }, this.options)
})

console.log(colorWithPlugin.isBlue()) // Output: true
// Usage
const color = dye("rgb(255, 0, 0)", { plugins: { grayscale } })

console.log(color.grayscale().rgb) // { r: 85, g: 85, b: 85, a: 1 }
```

For more information see [Working with Plugins Guide](docs/WORKING_WITH_PLUGINS.md).
**Built-in Plugins:** `invert`, `lighten`, `darken`, `saturate`, `desaturate`, `toCmyk`, `toHex`, `toHsl`, `toHsv`, `toRgb`

## Contributing
## Further Reading

- [API Reference](docs/API.md)
- [Working with Plugins](docs/guide/WORKING_WITH_PLUGINS.md)
- [Working with Parsers](docs/guide/WORKING_WITH_PARSERS.md)

Contributions are welcome! Please read the [Contributing Guide](CONTRIBUTING.md).
## Contributing

[**Leave a star and help spread the hues! 🎨⭐**](https://github.com/supitsdu/colorus-js)
Contributions are welcome! See the [Contributing Guide](CONTRIBUTING.md).
25 changes: 20 additions & 5 deletions biome.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
{
"files": {
"ignore": ["node_modules", "coverage", "docs", ".github", "_test"],
"include": ["src/*.ts", "test/*.ts"]
"ignore": [
"node_modules",
"coverage",
"docs",
".github",
"_test",
"build",
"dist"
],
"include": ["src/*.ts", "test/*.ts", "rollup.config.js", "jest.config.js"]
},
"organizeImports": { "enabled": true },
"formatter": {
Expand Down Expand Up @@ -31,18 +39,25 @@
"enabled": true,
"rules": {
"complexity": {
"noStaticOnlyClass": "warn"
"noStaticOnlyClass": "warn",
"noForEach": "off"
},
"suspicious": {
"noDebugger": "off",
"noConsoleLog": "info",
"noConsoleLog": "warn",
"noExplicitAny": "off",
"noConfusingVoidType": "off"
},
"style": {
"noShoutyConstants": "warn",
"useNamingConvention": "error",
"noNonNullAssertion": "off"
"noNonNullAssertion": "off",
"noInferrableTypes": "off",
"useNumberNamespace": "off"
},
"correctness": {
"noUnusedVariables": "warn",
"noUnusedImports": "warn"
}
}
}
Expand Down
68 changes: 68 additions & 0 deletions docs/API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# API Reference

Detailed information about the core functionalities, methods, and types available in the library.

## Core Method

### `dye(input: Colors.Input, options?: Dye.Options): Dye.Instance`

The primary function for creating a color instance.

**Parameters:**

- `input`: A color input, which can be either a color string (e.g., `"#FF5733"`, `"rgb(255, 0, 0)"`, `"hsl(120, 100%, 50%)"`, etc.) or an object representing RGB values.
- `options`: An optional configuration object to customize parsing and plugin behavior.
- `plugins`: An object containing custom plugins to extend functionality.
- `parsers`: An array of `ColorParser` instances to use for the input.
- `formatOptions`: Options for output formatting.

**Returns:** An instance of `Dye.Instance` with methods for color manipulation.

**Example:**

```javascript
import { dye } from "colorus-js"

const color = dye("rgb(255, 0, 0)")
console.log(color.hsl) // { h: 0, s: 100, l: 50, a: 1 }
```

## Color Types

Colorus.js supports various color representations defined as follows:

- **`Colors.Rgb`**: Represents colors in RGB format as `{ r: number, g: number, b: number, a: number }`.
- **`Colors.Hsl`**: Represents colors in HSL format as `{ h: number, s: number, l: number, a: number }`.
- **`Colors.Hsv`**: Represents colors in HSV format as `{ h: number, s: number, v: number, a: number }`.
- **`Colors.Cmyk`**: Represents colors in CMYK format as `{ c: number, m: number, y: number, k: number, a: number }`.

All these formats maintain an alpha channel for transparency, represented as a number (0 to 1).

## Color Properties

Each `Dye.Instance` provides access to various color properties calculated based on the initial input:

- `rgb`: Returns the RGB representation.
- `hsl`: Returns the HSL representation.
- `hsv`: Returns the HSV representation.
- `cmyk`: Returns the CMYK representation.
- `luminance`: Calculates and returns the luminance value.
- `alpha`: Returns the alpha (transparency) value.
- `hue`: Returns the hue value.
- `source`: Metadata and validity.
- `error`: Returns the error message, if any.

**Example:**

```javascript
const color = dye("hsl(120, 100%, 50%)")
console.log(color.rgb) // { r: 0, g: 255, b: 0, a: 1 }
```

## Built-in Parsers

For detailed information about the built-in parsers available in Colorus.js, please refer to the [Working with Parsers](/docs/guide/WORKING_WITH_PARSERS.md).

## Built-in Plugins

For detailed information about the built-in plugins available in Colorus.js, please refer to the [Working with Plugins](/docs/guide/WORKING_WITH_PLUGINS.md).
72 changes: 0 additions & 72 deletions docs/WORKING_WITH_PLUGINS.md

This file was deleted.

Loading

0 comments on commit 720ed03

Please sign in to comment.