Skip to content

Commit 445baaa

Browse files
Add a new packages @gitbook/colors (#2854)
Co-authored-by: Zeno Kapitein <[email protected]>
1 parent 7419ee7 commit 445baaa

File tree

14 files changed

+145
-28
lines changed

14 files changed

+145
-28
lines changed

.changeset/breezy-seals-yell.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@gitbook/colors': minor
3+
---
4+
5+
Initial release

bun.lock

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@
2222
"wrangler": "3.82.0",
2323
},
2424
},
25+
"packages/colors": {
26+
"name": "@gitbook/colors",
27+
"version": "0.1.0",
28+
"devDependencies": {
29+
"typescript": "^5.5.3",
30+
},
31+
},
2532
"packages/emoji-codepoints": {
2633
"name": "@gitbook/emoji-codepoints",
2734
"version": "0.2.0",
@@ -35,6 +42,7 @@
3542
"dependencies": {
3643
"@gitbook/api": "^0.93.0",
3744
"@gitbook/cache-do": "workspace:*",
45+
"@gitbook/colors": "workspace:*",
3846
"@gitbook/emoji-codepoints": "workspace:*",
3947
"@gitbook/icons": "workspace:*",
4048
"@gitbook/openapi-parser": "workspace:*",
@@ -594,6 +602,8 @@
594602

595603
"@gitbook/cache-do": ["@gitbook/cache-do@workspace:packages/cache-do"],
596604

605+
"@gitbook/colors": ["@gitbook/colors@workspace:packages/colors"],
606+
597607
"@gitbook/emoji-codepoints": ["@gitbook/emoji-codepoints@workspace:packages/emoji-codepoints"],
598608

599609
"@gitbook/fontawesome-pro": ["@gitbook/[email protected]", "", { "dependencies": { "@fortawesome/fontawesome-common-types": "^6.6.0" } }, "sha512-i4PgiuGyUb52Muhc52kK3aMJIMfMkA2RbPW30tre8a6M8T6mWTfYo6gafSgjNvF1vH29zcuB8oBYnF0gO4XcHA=="],

packages/colors/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
dist/

packages/colors/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# `@gitbook/colors`
2+
3+
A set of default colors and transformation functions used throughout the GitBook Open and app.

packages/colors/package.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "@gitbook/colors",
3+
"type": "module",
4+
"exports": {
5+
".": {
6+
"types": "./dist/index.d.ts",
7+
"development": "./src/index.ts",
8+
"default": "./dist/index.js"
9+
}
10+
},
11+
"version": "0.1.0",
12+
"devDependencies": {
13+
"typescript": "^5.5.3"
14+
},
15+
"scripts": {
16+
"build": "tsc",
17+
"typecheck": "tsc --noEmit",
18+
"dev": "tsc -w"
19+
},
20+
"files": [
21+
"dist",
22+
"src",
23+
"README.md",
24+
"CHANGELOG.md"
25+
]
26+
}

packages/colors/src/colors.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* Default primary color throughout the GitBook ecosystem.
3+
*/
4+
export const DEFAULT_PRIMARY_COLOR = '#346DDB';
5+
6+
/**
7+
* The darkest color that exists in GitBook, used as the relative minimum of every generated color scale.
8+
*/
9+
export const DARK_BASE = '#1D1D1D';
10+
11+
/**
12+
* The lightest color that exists in GitBook, used as the relative maximum of every generated color scale.
13+
*/
14+
export const LIGHT_BASE = '#FFFFFF';
15+
16+
/**
17+
* Used as the basis of all UI elements that are not colored by the primary color. Neutral gray by default, overridden by site customization.
18+
*/
19+
export const DEFAULT_TINT_COLOR = '#787878';
20+
21+
/**
22+
* Used for informational messages and neutral alerts.
23+
*/
24+
export const DEFAULT_HINT_INFO_COLOR = '#787878';
25+
26+
/**
27+
* Used for showing important information or non-critical warnings.
28+
*/
29+
export const DEFAULT_HINT_WARNING_COLOR = '#FE9A00';
30+
31+
/**
32+
* Used for destructive actions or raising attention to critical information.
33+
*/
34+
export const DEFAULT_HINT_DANGER_COLOR = '#FB2C36';
35+
36+
/**
37+
* Used for showing positive actions or achievements.
38+
*/
39+
export const DEFAULT_HINT_SUCCESS_COLOR = '#00C950';

packages/colors/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './colors';
2+
export * from './transformations';

packages/gitbook/src/lib/colors.ts renamed to packages/colors/src/transformations.ts

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { DARK_BASE, LIGHT_BASE, DEFAULT_TINT_COLOR } from './colors';
2+
13
type ColorShades = {
24
[key: string]: string;
35
};
@@ -6,9 +8,6 @@ type RGBColor = [number, number, number];
68
type OKLABColor = { L: number; A: number; B: number };
79
type OKLCHColor = { L: number; C: number; H: number };
810

9-
export const DARK_BASE = '#1d1d1d';
10-
export const LIGHT_BASE = '#ffffff';
11-
export const DEFAULT_TINT_COLOR = '#787878';
1211
const D65 = [95.047, 100.0, 108.883]; // Reference white (D65)
1312

1413
export enum ColorCategory {
@@ -226,7 +225,7 @@ export function colorScale(
226225
/**
227226
* Convert a hex color to an RGB color set.
228227
*/
229-
function hexToRgbArray(hex: string): RGBColor {
228+
export function hexToRgbArray(hex: string): RGBColor {
230229
const originalHex = hex;
231230

232231
let value = hex.replace('#', '');
@@ -252,7 +251,7 @@ function hexToRgbArray(hex: string): RGBColor {
252251
/**
253252
* Convert a RGB color set to a hex color.
254253
*/
255-
function rgbArrayToHex(rgb: RGBColor): string {
254+
export function rgbArrayToHex(rgb: RGBColor): string {
256255
return `#${rgb
257256
.map((channel) => {
258257
const component = channel.toString(16);
@@ -262,7 +261,7 @@ function rgbArrayToHex(rgb: RGBColor): string {
262261
.join('')}`;
263262
}
264263

265-
function getColor(percentage: number, start: RGBColor, end: RGBColor) {
264+
export function getColor(percentage: number, start: RGBColor, end: RGBColor) {
266265
const rgb = end.map((channel, index) => {
267266
return Math.round(channel + percentage * (start[index] - channel));
268267
});
@@ -271,21 +270,21 @@ function getColor(percentage: number, start: RGBColor, end: RGBColor) {
271270
}
272271

273272
// Utility constants and helper functions
274-
function rgbToLinear(rgb: RGBColor): [number, number, number] {
273+
export function rgbToLinear(rgb: RGBColor): [number, number, number] {
275274
return rgb.map((v) => {
276275
const scaled = v / 255;
277276
return scaled <= 0.04045 ? scaled / 12.92 : ((scaled + 0.055) / 1.055) ** 2.4;
278277
}) as [number, number, number];
279278
}
280279

281-
function linearToRgb(linear: [number, number, number]): RGBColor {
280+
export function linearToRgb(linear: [number, number, number]): RGBColor {
282281
return linear.map((v) => {
283282
const scaled = v <= 0.0031308 ? 12.92 * v : 1.055 * v ** (1 / 2.4) - 0.055;
284283
return Math.round(Math.max(0, Math.min(1, scaled)) * 255);
285284
}) as RGBColor;
286285
}
287286

288-
function rgbToOklab(rgb: RGBColor): OKLABColor {
287+
export function rgbToOklab(rgb: RGBColor): OKLABColor {
289288
const [r, g, b] = rgbToLinear(rgb);
290289

291290
const l = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b;
@@ -303,7 +302,7 @@ function rgbToOklab(rgb: RGBColor): OKLABColor {
303302
};
304303
}
305304

306-
function oklabToRgb(oklab: OKLABColor): RGBColor {
305+
export function oklabToRgb(oklab: OKLABColor): RGBColor {
307306
const { L, A, B } = oklab;
308307

309308
const lRoot = L + 0.3963377774 * A + 0.2158037573 * B;
@@ -321,14 +320,14 @@ function oklabToRgb(oklab: OKLABColor): RGBColor {
321320
return linearToRgb([r, g, b]);
322321
}
323322

324-
function oklabToOklch(oklab: OKLABColor): OKLCHColor {
323+
export function oklabToOklch(oklab: OKLABColor): OKLCHColor {
325324
const { L, A, B } = oklab;
326325
const C = Math.sqrt(A ** 2 + B ** 2);
327326
const H = (Math.atan2(B, A) * 180) / Math.PI;
328327
return { L, C, H: H < 0 ? H + 360 : H };
329328
}
330329

331-
function oklchToOklab(oklch: OKLCHColor): OKLABColor {
330+
export function oklchToOklab(oklch: OKLCHColor): OKLABColor {
332331
const { L, C, H } = oklch;
333332
const rad = (H * Math.PI) / 180;
334333
return {
@@ -338,15 +337,15 @@ function oklchToOklab(oklch: OKLCHColor): OKLABColor {
338337
};
339338
}
340339

341-
function rgbToOklch(rgb: RGBColor): OKLCHColor {
340+
export function rgbToOklch(rgb: RGBColor): OKLCHColor {
342341
return oklabToOklch(rgbToOklab(rgb));
343342
}
344343

345-
function oklchToRgb(oklch: OKLCHColor): RGBColor {
344+
export function oklchToRgb(oklch: OKLCHColor): RGBColor {
346345
return oklabToRgb(oklchToOklab(oklch));
347346
}
348347

349-
function rgbToXyz(rgb: RGBColor): [number, number, number] {
348+
export function rgbToXyz(rgb: RGBColor): [number, number, number] {
350349
const [r, g, b] = rgbToLinear(rgb);
351350
return [
352351
(r * 0.4124564 + g * 0.3575761 + b * 0.1804375) * 100,
@@ -355,7 +354,11 @@ function rgbToXyz(rgb: RGBColor): [number, number, number] {
355354
];
356355
}
357356

358-
function xyzToLab65(xyz: [number, number, number]): { L: number; A: number; B: number } {
357+
export function xyzToLab65(xyz: [number, number, number]): {
358+
L: number;
359+
A: number;
360+
B: number;
361+
} {
359362
const [x, y, z] = xyz.map((v, i) => {
360363
const scaled = v / D65[i];
361364
return scaled > 0.008856 ? Math.cbrt(scaled) : 7.787 * scaled + 16 / 116;
@@ -368,15 +371,15 @@ function xyzToLab65(xyz: [number, number, number]): { L: number; A: number; B: n
368371
};
369372
}
370373

371-
function rgbTolab65(rgb: RGBColor): { L: number; A: number; B: number } {
374+
export function rgbTolab65(rgb: RGBColor): { L: number; A: number; B: number } {
372375
return xyzToLab65(rgbToXyz(rgb));
373376
}
374377

375378
/*
376379
Delta Phi Star perceptual lightness contrast by Andrew Somers:
377380
https://github.com/Myndex/deltaphistar
378381
*/
379-
const PHI = 0.5 + Math.sqrt(1.25);
382+
export const PHI = 0.5 + Math.sqrt(1.25);
380383

381384
export function dpsContrast(a: RGBColor, b: RGBColor) {
382385
const dps = Math.abs(rgbTolab65(a).L ** PHI - rgbTolab65(b).L ** PHI);
@@ -387,7 +390,10 @@ export function dpsContrast(a: RGBColor, b: RGBColor) {
387390
export function colorContrast(background: string, foreground: string[] = [LIGHT_BASE, DARK_BASE]) {
388391
const bg = hexToRgbArray(background);
389392

390-
const best: { color?: RGBColor; contrast: number } = { color: undefined, contrast: 0 };
393+
const best: { color?: RGBColor; contrast: number } = {
394+
color: undefined,
395+
contrast: 0,
396+
};
391397
for (const color of foreground) {
392398
const c = hexToRgbArray(color);
393399

packages/colors/tsconfig.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"compilerOptions": {
3+
"target": "esnext",
4+
"lib": ["dom", "dom.iterable", "esnext"],
5+
"allowJs": true,
6+
"skipLibCheck": true,
7+
"strict": true,
8+
"noEmit": false,
9+
"declaration": true,
10+
"outDir": "dist",
11+
"esModuleInterop": true,
12+
"module": "esnext",
13+
"moduleResolution": "bundler",
14+
"resolveJsonModule": true,
15+
"isolatedModules": true,
16+
"jsx": "react",
17+
"incremental": true,
18+
"types": [
19+
"bun-types" // add Bun global
20+
]
21+
},
22+
"include": ["src/**/*.ts", "src/**/*.tsx"],
23+
"exclude": ["node_modules"]
24+
}

packages/gitbook/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"dependencies": {
2020
"@gitbook/api": "^0.93.0",
2121
"@gitbook/cache-do": "workspace:*",
22+
"@gitbook/colors": "workspace:*",
2223
"@gitbook/emoji-codepoints": "workspace:*",
2324
"@gitbook/icons": "workspace:*",
2425
"@gitbook/openapi-parser": "workspace:*",

0 commit comments

Comments
 (0)