Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/breezy-seals-yell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@gitbook/colors': minor
---

Initial release
10 changes: 10 additions & 0 deletions bun.lock
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
"wrangler": "3.82.0",
},
},
"packages/colors": {
"name": "@gitbook/colors",
"version": "0.1.0",
"devDependencies": {
"typescript": "^5.5.3",
},
},
"packages/emoji-codepoints": {
"name": "@gitbook/emoji-codepoints",
"version": "0.2.0",
Expand All @@ -35,6 +42,7 @@
"dependencies": {
"@gitbook/api": "^0.93.0",
"@gitbook/cache-do": "workspace:*",
"@gitbook/colors": "workspace:*",
"@gitbook/emoji-codepoints": "workspace:*",
"@gitbook/icons": "workspace:*",
"@gitbook/openapi-parser": "workspace:*",
Expand Down Expand Up @@ -594,6 +602,8 @@

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

"@gitbook/colors": ["@gitbook/colors@workspace:packages/colors"],

"@gitbook/emoji-codepoints": ["@gitbook/emoji-codepoints@workspace:packages/emoji-codepoints"],

"@gitbook/fontawesome-pro": ["@gitbook/[email protected]", "", { "dependencies": { "@fortawesome/fontawesome-common-types": "^6.6.0" } }, "sha512-i4PgiuGyUb52Muhc52kK3aMJIMfMkA2RbPW30tre8a6M8T6mWTfYo6gafSgjNvF1vH29zcuB8oBYnF0gO4XcHA=="],
Expand Down
1 change: 1 addition & 0 deletions packages/colors/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist/
3 changes: 3 additions & 0 deletions packages/colors/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# `@gitbook/colors`

A set of default colors and transformation functions used throughout the GitBook Open and app.
26 changes: 26 additions & 0 deletions packages/colors/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "@gitbook/colors",
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"development": "./src/index.ts",
"default": "./dist/index.js"
}
},
"version": "0.1.0",
"devDependencies": {
"typescript": "^5.5.3"
},
"scripts": {
"build": "tsc",
"typecheck": "tsc --noEmit",
"dev": "tsc -w"
},
"files": [
"dist",
"src",
"README.md",
"CHANGELOG.md"
]
}
39 changes: 39 additions & 0 deletions packages/colors/src/colors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Default primary color throughout the GitBook ecosystem.
*/
export const DEFAULT_PRIMARY_COLOR = '#346DDB';

/**
* The darkest color that exists in GitBook, used as the relative minimum of every generated color scale.
*/
export const DARK_BASE = '#1D1D1D';

/**
* The lightest color that exists in GitBook, used as the relative maximum of every generated color scale.
*/
export const LIGHT_BASE = '#FFFFFF';

/**
* Used as the basis of all UI elements that are not colored by the primary color. Neutral gray by default, overridden by site customization.
*/
export const DEFAULT_TINT_COLOR = '#787878';

/**
* Used for informational messages and neutral alerts.
*/
export const DEFAULT_HINT_INFO_COLOR = '#787878';

/**
* Used for showing important information or non-critical warnings.
*/
export const DEFAULT_HINT_WARNING_COLOR = '#FE9A00';

/**
* Used for destructive actions or raising attention to critical information.
*/
export const DEFAULT_HINT_DANGER_COLOR = '#FB2C36';

/**
* Used for showing positive actions or achievements.
*/
export const DEFAULT_HINT_SUCCESS_COLOR = '#00C950';
2 changes: 2 additions & 0 deletions packages/colors/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './colors';
export * from './transformations';
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { DARK_BASE, LIGHT_BASE, DEFAULT_TINT_COLOR } from './colors';

type ColorShades = {
[key: string]: string;
};
Expand All @@ -6,9 +8,6 @@ type RGBColor = [number, number, number];
type OKLABColor = { L: number; A: number; B: number };
type OKLCHColor = { L: number; C: number; H: number };

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

export enum ColorCategory {
Expand Down Expand Up @@ -226,7 +225,7 @@ export function colorScale(
/**
* Convert a hex color to an RGB color set.
*/
function hexToRgbArray(hex: string): RGBColor {
export function hexToRgbArray(hex: string): RGBColor {
const originalHex = hex;

let value = hex.replace('#', '');
Expand All @@ -252,7 +251,7 @@ function hexToRgbArray(hex: string): RGBColor {
/**
* Convert a RGB color set to a hex color.
*/
function rgbArrayToHex(rgb: RGBColor): string {
export function rgbArrayToHex(rgb: RGBColor): string {
return `#${rgb
.map((channel) => {
const component = channel.toString(16);
Expand All @@ -262,7 +261,7 @@ function rgbArrayToHex(rgb: RGBColor): string {
.join('')}`;
}

function getColor(percentage: number, start: RGBColor, end: RGBColor) {
export function getColor(percentage: number, start: RGBColor, end: RGBColor) {
const rgb = end.map((channel, index) => {
return Math.round(channel + percentage * (start[index] - channel));
});
Expand All @@ -271,21 +270,21 @@ function getColor(percentage: number, start: RGBColor, end: RGBColor) {
}

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

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

function rgbToOklab(rgb: RGBColor): OKLABColor {
export function rgbToOklab(rgb: RGBColor): OKLABColor {
const [r, g, b] = rgbToLinear(rgb);

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

function oklabToRgb(oklab: OKLABColor): RGBColor {
export function oklabToRgb(oklab: OKLABColor): RGBColor {
const { L, A, B } = oklab;

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

function oklabToOklch(oklab: OKLABColor): OKLCHColor {
export function oklabToOklch(oklab: OKLABColor): OKLCHColor {
const { L, A, B } = oklab;
const C = Math.sqrt(A ** 2 + B ** 2);
const H = (Math.atan2(B, A) * 180) / Math.PI;
return { L, C, H: H < 0 ? H + 360 : H };
}

function oklchToOklab(oklch: OKLCHColor): OKLABColor {
export function oklchToOklab(oklch: OKLCHColor): OKLABColor {
const { L, C, H } = oklch;
const rad = (H * Math.PI) / 180;
return {
Expand All @@ -338,15 +337,15 @@ function oklchToOklab(oklch: OKLCHColor): OKLABColor {
};
}

function rgbToOklch(rgb: RGBColor): OKLCHColor {
export function rgbToOklch(rgb: RGBColor): OKLCHColor {
return oklabToOklch(rgbToOklab(rgb));
}

function oklchToRgb(oklch: OKLCHColor): RGBColor {
export function oklchToRgb(oklch: OKLCHColor): RGBColor {
return oklabToRgb(oklchToOklab(oklch));
}

function rgbToXyz(rgb: RGBColor): [number, number, number] {
export function rgbToXyz(rgb: RGBColor): [number, number, number] {
const [r, g, b] = rgbToLinear(rgb);
return [
(r * 0.4124564 + g * 0.3575761 + b * 0.1804375) * 100,
Expand All @@ -355,7 +354,11 @@ function rgbToXyz(rgb: RGBColor): [number, number, number] {
];
}

function xyzToLab65(xyz: [number, number, number]): { L: number; A: number; B: number } {
export function xyzToLab65(xyz: [number, number, number]): {
L: number;
A: number;
B: number;
} {
const [x, y, z] = xyz.map((v, i) => {
const scaled = v / D65[i];
return scaled > 0.008856 ? Math.cbrt(scaled) : 7.787 * scaled + 16 / 116;
Expand All @@ -368,15 +371,15 @@ function xyzToLab65(xyz: [number, number, number]): { L: number; A: number; B: n
};
}

function rgbTolab65(rgb: RGBColor): { L: number; A: number; B: number } {
export function rgbTolab65(rgb: RGBColor): { L: number; A: number; B: number } {
return xyzToLab65(rgbToXyz(rgb));
}

/*
Delta Phi Star perceptual lightness contrast by Andrew Somers:
https://github.com/Myndex/deltaphistar
*/
const PHI = 0.5 + Math.sqrt(1.25);
export const PHI = 0.5 + Math.sqrt(1.25);

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

const best: { color?: RGBColor; contrast: number } = { color: undefined, contrast: 0 };
const best: { color?: RGBColor; contrast: number } = {
color: undefined,
contrast: 0,
};
for (const color of foreground) {
const c = hexToRgbArray(color);

Expand Down
24 changes: 24 additions & 0 deletions packages/colors/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"compilerOptions": {
"target": "esnext",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": false,
"declaration": true,
"outDir": "dist",
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "react",
"incremental": true,
"types": [
"bun-types" // add Bun global
]
},
"include": ["src/**/*.ts", "src/**/*.tsx"],
"exclude": ["node_modules"]
}
1 change: 1 addition & 0 deletions packages/gitbook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"dependencies": {
"@gitbook/api": "^0.93.0",
"@gitbook/cache-do": "workspace:*",
"@gitbook/colors": "workspace:*",
"@gitbook/emoji-codepoints": "workspace:*",
"@gitbook/icons": "workspace:*",
"@gitbook/openapi-parser": "workspace:*",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { CustomizationHeaderPreset } from '@gitbook/api';
import { colorContrast } from '@gitbook/colors';
import { redirect } from 'next/navigation';
import { ImageResponse } from 'next/og';
import { NextRequest } from 'next/server';
import React from 'react';

import { googleFontsMap } from '@/fonts';
import { colorContrast } from '@/lib/colors';
import { getAbsoluteHref } from '@/lib/links';
import { filterOutNullable } from '@/lib/typescript';
import { getContentTitle } from '@/lib/utils';
Expand Down
2 changes: 1 addition & 1 deletion packages/gitbook/src/components/Ads/AdCoverRendering.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { SiteInsightsAd } from '@gitbook/api';
import { hexToRgba } from '@gitbook/colors';
import * as React from 'react';

import { hexToRgba } from '@/lib/colors';
import { getResizedImageURL } from '@/lib/images';
import { tcls } from '@/lib/tailwind';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ import {
type CustomizationTint,
type SiteCustomizationSettings,
} from '@gitbook/api';
import { IconsProvider, IconStyle } from '@gitbook/icons';

import { fontNotoColorEmoji, fonts, ibmPlexMono } from '@/fonts';
import { getSpaceLanguage } from '@/intl/server';
import { getStaticFileURL } from '@/lib/assets';
import {
colorContrast,
colorScale,
type ColorScaleOptions,
DEFAULT_TINT_COLOR,
hexToRgb,
} from '@/lib/colors';
} from '@gitbook/colors';
import { IconsProvider, IconStyle } from '@gitbook/icons';

import { fontNotoColorEmoji, fonts, ibmPlexMono } from '@/fonts';
import { getSpaceLanguage } from '@/intl/server';
import { getStaticFileURL } from '@/lib/assets';
import { tcls } from '@/lib/tailwind';

import { ClientContexts } from './ClientContexts';
Expand Down
2 changes: 1 addition & 1 deletion packages/gitbook/tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import typography from '@tailwindcss/typography';
import type { Config } from 'tailwindcss';
import plugin from 'tailwindcss/plugin';

import { ColorCategory, hexToRgb, scale, shadesOfColor } from './src/lib/colors';
import { ColorCategory, hexToRgb, scale, shadesOfColor } from '@gitbook/colors';

export const shades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900];
export const opacities = [0, 4, 8, 12, 16, 24, 40, 64, 72, 88, 96, 100];
Expand Down
Loading