Skip to content

Commit

Permalink
Add colour shades support
Browse files Browse the repository at this point in the history
This implementation is not complete and code is *probably* bad. Will
improve and fix remaining issues later.
  • Loading branch information
catuhana committed Jan 3, 2024
1 parent 44d5714 commit df92c9b
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 21 deletions.
9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@
"prepack": "pnpm build"
},
"dependencies": {
"@catppuccin/palette": "^1.0.1"
"@catppuccin/palette": "^1.0.1",
"culori": "^3.3.0"
},
"devDependencies": {
"@types/culori": "^2.0.4",
"@unocss/core": "^0.58.2",
"prettier": "^3.1.1",
"typescript": "^5.3.3",
Expand All @@ -48,5 +50,10 @@
"packageManager": "[email protected]",
"engines": {
"node": ">=16"
},
"pnpm": {
"patchedDependencies": {
"[email protected]": "patches/[email protected]"
}
}
}
12 changes: 12 additions & 0 deletions patches/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
diff --git a/package.json b/package.json
index a03ee24a4907bb93a9e4912ba5ce1046589b8408..fa80924eb29ff92881c58cf0e474bea6b67374ba 100644
--- a/package.json
+++ b/package.json
@@ -8,6 +8,7 @@
"jsdelivr": "./bundled/culori.umd.js",
"exports": {
"./require": "./bundled/culori.cjs",
+ "./export": "./bundled/culori.mjs",
".": "./src/index.js",
"./css": "./src/bootstrap/css.js",
"./all": "./src/bootstrap/all.js",
45 changes: 33 additions & 12 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const SHADE_RANGE = [
50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950,
] as const;
22 changes: 18 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ import {
flavorEntries as flavourEntries,
} from '@catppuccin/palette';

import { generateShadePalette } from './shade.ts';

import type { Preset } from '@unocss/core';
import type { ExtenderOptions } from './types.ts';

/**
* Extend theme to UnoCSS by using `extendTheme` function.
*/
export const extendCatppuccin = (options: ExtenderOptions = {}): Preset => {
const { prefix = 'ctp', defaultFlavour } = options;
const { prefix = 'ctp', defaultFlavour, generateShades = true } = options;

return {
name: 'unocss-catppuccin',
Expand All @@ -21,13 +23,25 @@ export const extendCatppuccin = (options: ExtenderOptions = {}): Preset => {
if (defaultFlavour && flavours[defaultFlavour]) {
for (let [colourName, colour] of flavours[defaultFlavour]
.colorEntries) {
target[colourName] = colour.hex;
if (target[colourName]) continue;

if (generateShades) {
target[colourName] ??= generateShadePalette(colour);
} else {
target[colourName] = colour.hex;
}
}
} else {
for (let [flavourName, flavour] of flavourEntries) {
target = target[flavourName] ??= {};
if (target[flavourName]) continue;

target[flavourName] ??= {};
for (let [colourName, colour] of flavour.colorEntries) {
target[colourName] = colour.hex;
if (generateShades) {
target[flavourName][colourName] = generateShadePalette(colour);
} else {
target[flavourName][colourName] = colour.hex;
}
}
}
}
Expand Down
50 changes: 50 additions & 0 deletions src/shade.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { formatHex, interpolate } from 'culori/export';

import { SHADE_RANGE } from './constants.ts';

import type { ColorFormat } from '@catppuccin/palette';

export const generateShadePalette = (colour: ColorFormat) => {
let resultObject = {} as Record<keyof typeof SHADE_RANGE | 'DEFAULT', string>;

const colourShade = mapLightnessToShadeRange(colour.hsl.l * 100);

const [lighten, darken] = SHADE_RANGE.reduce(
([lighten, darken], shade) => {
if (shade < colourShade) {
return [[...lighten, shade], darken];
} else if (shade > colourShade) {
return [lighten, [...darken, shade]];
}
return [lighten, darken];
},
[[], []] as number[][]
);

lighten.reverse().map((shade, i) => {
resultObject[shade] ??= formatHex(
interpolate(
[colour.hex, 'white'],
'hsl'
)((i + 1) / (SHADE_RANGE.length - 1))
);
});
darken.map((shade, i) => {
resultObject[shade] ??= formatHex(
interpolate(
[colour.hex, 'black'],
'hsl'
)((i + 1) / (SHADE_RANGE.length - 1))
);
});

resultObject['DEFAULT'] = resultObject[colourShade] = colour.hex;

return resultObject;
};

function mapLightnessToShadeRange(lightness: number) {
return SHADE_RANGE[
Math.floor((100 - lightness) / (100 / SHADE_RANGE.length))
];
}
19 changes: 17 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ export interface ExtenderOptions extends PresetOptions {
* <!-- Let's make it `meow` -->
* <p class='text-meow-flamingo'>Hello world!</p>
*
* <!-- Lets make it a falsy value except `undefined`, for example `false` -->
* <!-- This will use current preset's colour! -->
* <!-- Lets make it a falsy value except `undefined` -->
* <!-- This will use current preset's colour instead
* to not override preset values. -->
* <p class='bg-red'>Hello world!</p>
* <!-- To use Catppuccin's colour, add the `ctp` prefix -->
* <p class='bg-ctp-red'>Hello world!</p>
Expand All @@ -40,4 +41,18 @@ export interface ExtenderOptions extends PresetOptions {
* @default undefined
*/
defaultFlavour?: keyof CatppuccinFlavors;
/**
* Generate dark and light shades for colours or not.
*
* Note: This might affect the performance, so it's
* recommended to disable this if shades won't be used.
*
* @example
* ```html
* <p class="bg-ctp-frappe-rose-300">Hello world!</p>
* ```
*
* @default true
*/
generateShades?: boolean
}
5 changes: 3 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
"lib": ["ES2020", "DOM"],
"module": "Node16",
"target": "ES2020",
"moduleResolution": "node16",
"moduleResolution": "Node16",
"strict": true,
"noEmit": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"esModuleInterop": true,
"allowImportingTsExtensions": true,
"forceConsistentCasingInFileNames": true
}
}

0 comments on commit df92c9b

Please sign in to comment.