working jump to definition with tests
This commit is contained in:
@@ -1,74 +0,0 @@
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import themes from "./themes";
|
||||
import Theme from "./themes/common/theme";
|
||||
import { colors, fontFamilies, fontSizes, fontWeights, sizes } from "./tokens";
|
||||
|
||||
// Organize theme tokens
|
||||
function themeTokens(theme: Theme) {
|
||||
return {
|
||||
meta: {
|
||||
themeName: theme.name,
|
||||
},
|
||||
text: theme.textColor,
|
||||
icon: theme.iconColor,
|
||||
background: theme.backgroundColor,
|
||||
border: theme.borderColor,
|
||||
editor: theme.editor,
|
||||
syntax: {
|
||||
primary: theme.syntax.primary.color,
|
||||
comment: theme.syntax.comment.color,
|
||||
keyword: theme.syntax.keyword.color,
|
||||
function: theme.syntax.function.color,
|
||||
type: theme.syntax.type.color,
|
||||
variant: theme.syntax.variant.color,
|
||||
property: theme.syntax.property.color,
|
||||
enum: theme.syntax.enum.color,
|
||||
operator: theme.syntax.operator.color,
|
||||
string: theme.syntax.string.color,
|
||||
number: theme.syntax.number.color,
|
||||
boolean: theme.syntax.boolean.color,
|
||||
},
|
||||
player: theme.player,
|
||||
shadow: theme.shadow,
|
||||
};
|
||||
}
|
||||
|
||||
// Organize core tokens
|
||||
const coreTokens = {
|
||||
color: colors,
|
||||
text: {
|
||||
family: fontFamilies,
|
||||
weight: fontWeights,
|
||||
},
|
||||
size: sizes,
|
||||
fontSize: fontSizes,
|
||||
};
|
||||
|
||||
const combinedTokens: any = {};
|
||||
|
||||
const distPath = path.resolve(`${__dirname}/../dist`);
|
||||
for (const file of fs.readdirSync(distPath)) {
|
||||
fs.unlinkSync(path.join(distPath, file));
|
||||
}
|
||||
|
||||
// Add core tokens to the combined tokens and write `core.json`.
|
||||
// We write `core.json` as a separate file for the design team's convenience, but it isn't consumed by Figma Tokens directly.
|
||||
const corePath = path.join(distPath, "core.json");
|
||||
fs.writeFileSync(corePath, JSON.stringify(coreTokens, null, 2));
|
||||
console.log(`- ${corePath} created`);
|
||||
combinedTokens.core = coreTokens;
|
||||
|
||||
// Add each theme to the combined tokens and write ${theme}.json.
|
||||
// We write `${theme}.json` as a separate file for the design team's convenience, but it isn't consumed by Figma Tokens directly.
|
||||
themes.forEach((theme) => {
|
||||
const themePath = `${distPath}/${theme.name}.json`
|
||||
fs.writeFileSync(themePath, JSON.stringify(themeTokens(theme), null, 2));
|
||||
console.log(`- ${themePath} created`);
|
||||
combinedTokens[theme.name] = themeTokens(theme);
|
||||
});
|
||||
|
||||
// Write combined tokens to `tokens.json`. This file is consumed by the Figma Tokens plugin to keep our designs consistent with the app.
|
||||
const combinedPath = path.resolve(`${distPath}/tokens.json`);
|
||||
fs.writeFileSync(combinedPath, JSON.stringify(combinedTokens, null, 2));
|
||||
console.log(`- ${combinedPath} created`);
|
||||
@@ -0,0 +1,65 @@
|
||||
export const fontFamilies = {
|
||||
sans: "Zed Sans",
|
||||
mono: "Zed Mono",
|
||||
}
|
||||
|
||||
export const fontSizes = {
|
||||
"3xs": 8,
|
||||
"2xs": 10,
|
||||
xs: 12,
|
||||
sm: 14,
|
||||
md: 16,
|
||||
lg: 18,
|
||||
xl: 20,
|
||||
};
|
||||
|
||||
export type FontWeight = "thin"
|
||||
| "extra_light"
|
||||
| "light"
|
||||
| "normal"
|
||||
| "medium"
|
||||
| "semibold"
|
||||
| "bold"
|
||||
| "extra_bold"
|
||||
| "black";
|
||||
export const fontWeights: { [key: string]: FontWeight } = {
|
||||
thin: "thin",
|
||||
extra_light: "extra_light",
|
||||
light: "light",
|
||||
normal: "normal",
|
||||
medium: "medium",
|
||||
semibold: "semibold",
|
||||
bold: "bold",
|
||||
extra_bold: "extra_bold",
|
||||
black: "black"
|
||||
};
|
||||
|
||||
export const sizes = {
|
||||
px: 1,
|
||||
xs: 2,
|
||||
sm: 4,
|
||||
md: 6,
|
||||
lg: 8,
|
||||
xl: 12,
|
||||
};
|
||||
|
||||
// export const colors = {
|
||||
// neutral: colorRamp(["white", "black"], { steps: 37, increment: 25 }), // (900/25) + 1
|
||||
// rose: colorRamp("#F43F5EFF"),
|
||||
// red: colorRamp("#EF4444FF"),
|
||||
// orange: colorRamp("#F97316FF"),
|
||||
// amber: colorRamp("#F59E0BFF"),
|
||||
// yellow: colorRamp("#EAB308FF"),
|
||||
// lime: colorRamp("#84CC16FF"),
|
||||
// green: colorRamp("#22C55EFF"),
|
||||
// emerald: colorRamp("#10B981FF"),
|
||||
// teal: colorRamp("#14B8A6FF"),
|
||||
// cyan: colorRamp("#06BBD4FF"),
|
||||
// sky: colorRamp("#0EA5E9FF"),
|
||||
// blue: colorRamp("#3B82F6FF"),
|
||||
// indigo: colorRamp("#6366F1FF"),
|
||||
// violet: colorRamp("#8B5CF6FF"),
|
||||
// purple: colorRamp("#A855F7FF"),
|
||||
// fuschia: colorRamp("#D946E4FF"),
|
||||
// pink: colorRamp("#EC4899FF"),
|
||||
// }
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
backgroundColor,
|
||||
border,
|
||||
player,
|
||||
modalShadow,
|
||||
text,
|
||||
TextColor,
|
||||
popoverShadow
|
||||
@@ -80,15 +79,15 @@ export default function chatPanel(theme: Theme) {
|
||||
...message,
|
||||
body: {
|
||||
...message.body,
|
||||
color: theme.textColor.muted.value,
|
||||
color: theme.textColor.muted,
|
||||
},
|
||||
sender: {
|
||||
...message.sender,
|
||||
color: theme.textColor.muted.value,
|
||||
color: theme.textColor.muted,
|
||||
},
|
||||
timestamp: {
|
||||
...message.timestamp,
|
||||
color: theme.textColor.muted.value,
|
||||
color: theme.textColor.muted,
|
||||
},
|
||||
},
|
||||
inputEditor: {
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import chroma from "chroma-js";
|
||||
import { isIPv4 } from "net";
|
||||
import Theme, { BackgroundColorSet } from "../themes/common/theme";
|
||||
import { fontFamilies, fontSizes, FontWeight } from "../tokens";
|
||||
import { Color } from "../utils/color";
|
||||
import { fontFamilies, fontSizes, FontWeight } from "../common";
|
||||
|
||||
export type TextColor = keyof Theme["textColor"];
|
||||
export function text(
|
||||
@@ -15,16 +12,16 @@ export function text(
|
||||
underline?: boolean;
|
||||
}
|
||||
) {
|
||||
let size = fontSizes[properties?.size || "sm"].value;
|
||||
let size = fontSizes[properties?.size || "sm"];
|
||||
return {
|
||||
family: fontFamilies[fontFamily].value,
|
||||
color: theme.textColor[color].value,
|
||||
family: fontFamilies[fontFamily],
|
||||
color: theme.textColor[color],
|
||||
...properties,
|
||||
size,
|
||||
};
|
||||
}
|
||||
export function textColor(theme: Theme, color: TextColor) {
|
||||
return theme.textColor[color].value;
|
||||
return theme.textColor[color];
|
||||
}
|
||||
|
||||
export type BorderColor = keyof Theme["borderColor"];
|
||||
@@ -48,19 +45,19 @@ export function border(
|
||||
};
|
||||
}
|
||||
export function borderColor(theme: Theme, color: BorderColor) {
|
||||
return theme.borderColor[color].value;
|
||||
return theme.borderColor[color];
|
||||
}
|
||||
|
||||
export type IconColor = keyof Theme["iconColor"];
|
||||
export function iconColor(theme: Theme, color: IconColor) {
|
||||
return theme.iconColor[color].value;
|
||||
return theme.iconColor[color];
|
||||
}
|
||||
|
||||
export type PlayerIndex = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
|
||||
export interface Player {
|
||||
selection: {
|
||||
cursor: Color;
|
||||
selection: Color;
|
||||
cursor: string;
|
||||
selection: string;
|
||||
};
|
||||
}
|
||||
export function player(
|
||||
@@ -69,8 +66,8 @@ export function player(
|
||||
): Player {
|
||||
return {
|
||||
selection: {
|
||||
cursor: theme.player[playerNumber].cursorColor.value,
|
||||
selection: theme.player[playerNumber].selectionColor.value,
|
||||
cursor: theme.player[playerNumber].cursorColor,
|
||||
selection: theme.player[playerNumber].selectionColor,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -81,14 +78,14 @@ export function backgroundColor(
|
||||
theme: Theme,
|
||||
name: BackgroundColor,
|
||||
state?: BackgroundState,
|
||||
): Color {
|
||||
return theme.backgroundColor[name][state || "base"].value;
|
||||
): string {
|
||||
return theme.backgroundColor[name][state || "base"];
|
||||
}
|
||||
|
||||
export function modalShadow(theme: Theme) {
|
||||
return {
|
||||
blur: 16,
|
||||
color: theme.shadow.value,
|
||||
color: theme.shadow,
|
||||
offset: [0, 2],
|
||||
};
|
||||
}
|
||||
@@ -96,7 +93,7 @@ export function modalShadow(theme: Theme) {
|
||||
export function popoverShadow(theme: Theme) {
|
||||
return {
|
||||
blur: 4,
|
||||
color: theme.shadow.value,
|
||||
color: theme.shadow,
|
||||
offset: [1, 2],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -43,28 +43,28 @@ export default function editor(theme: Theme) {
|
||||
for (const syntaxKey in theme.syntax) {
|
||||
const style = theme.syntax[syntaxKey];
|
||||
syntax[syntaxKey] = {
|
||||
color: style.color.value,
|
||||
weight: style.weight.value,
|
||||
color: style.color,
|
||||
weight: style.weight,
|
||||
underline: style.underline,
|
||||
italic: style.italic,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
textColor: theme.syntax.primary.color.value,
|
||||
textColor: theme.syntax.primary.color,
|
||||
background: backgroundColor(theme, 500),
|
||||
activeLineBackground: theme.editor.line.active.value,
|
||||
activeLineBackground: theme.editor.line.active,
|
||||
codeActionsIndicator: iconColor(theme, "muted"),
|
||||
diffBackgroundDeleted: backgroundColor(theme, "error"),
|
||||
diffBackgroundInserted: backgroundColor(theme, "ok"),
|
||||
documentHighlightReadBackground: theme.editor.highlight.occurrence.value,
|
||||
documentHighlightWriteBackground: theme.editor.highlight.activeOccurrence.value,
|
||||
errorColor: theme.textColor.error.value,
|
||||
documentHighlightReadBackground: theme.editor.highlight.occurrence,
|
||||
documentHighlightWriteBackground: theme.editor.highlight.activeOccurrence,
|
||||
errorColor: theme.textColor.error,
|
||||
gutterBackground: backgroundColor(theme, 500),
|
||||
gutterPaddingFactor: 3.5,
|
||||
highlightedLineBackground: theme.editor.line.highlighted.value,
|
||||
lineNumber: theme.editor.gutter.primary.value,
|
||||
lineNumberActive: theme.editor.gutter.active.value,
|
||||
highlightedLineBackground: theme.editor.line.highlighted,
|
||||
lineNumber: theme.editor.gutter.primary,
|
||||
lineNumberActive: theme.editor.gutter.active,
|
||||
renameFade: 0.6,
|
||||
unnecessaryCodeFade: 0.5,
|
||||
selection: player(theme, 1).selection,
|
||||
@@ -120,7 +120,7 @@ export default function editor(theme: Theme) {
|
||||
},
|
||||
},
|
||||
diagnosticPathHeader: {
|
||||
background: theme.editor.line.active.value,
|
||||
background: theme.editor.line.active,
|
||||
textScaleFactor: 0.857,
|
||||
filename: text(theme, "mono", "primary", { size: "sm" }),
|
||||
path: {
|
||||
@@ -139,6 +139,10 @@ export default function editor(theme: Theme) {
|
||||
invalidInformationDiagnostic: diagnostic(theme, "muted"),
|
||||
invalidWarningDiagnostic: diagnostic(theme, "muted"),
|
||||
hover_popover: hoverPopover(theme),
|
||||
link_definition: {
|
||||
color: theme.syntax.linkUri.color,
|
||||
underline: theme.syntax.linkUri.underline,
|
||||
},
|
||||
jumpIcon: {
|
||||
color: iconColor(theme, "muted"),
|
||||
iconWidth: 20,
|
||||
|
||||
@@ -22,6 +22,6 @@ export default function HoverPopover(theme: Theme) {
|
||||
padding: { top: 4 },
|
||||
},
|
||||
prose: text(theme, "sans", "primary", { "size": "sm" }),
|
||||
highlight: theme.editor.highlight.occurrence.value,
|
||||
highlight: theme.editor.highlight.occurrence,
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ export default function search(theme: Theme) {
|
||||
};
|
||||
|
||||
return {
|
||||
matchBackground: theme.editor.highlight.match.value,
|
||||
matchBackground: theme.editor.highlight.match,
|
||||
tabIconSpacing: 8,
|
||||
tabIconWidth: 14,
|
||||
optionButton: {
|
||||
|
||||
@@ -13,7 +13,7 @@ export default function updateNotification(theme: Theme): Object {
|
||||
...text(theme, "sans", "secondary", { size: "xs" }),
|
||||
margin: { left: headerPadding, top: 6, bottom: 6 },
|
||||
hover: {
|
||||
color: theme.textColor["active"].value
|
||||
color: theme.textColor["active"]
|
||||
}
|
||||
},
|
||||
dismissButton: {
|
||||
|
||||
@@ -147,7 +147,7 @@ export default function workspace(theme: Theme) {
|
||||
},
|
||||
disconnectedOverlay: {
|
||||
...text(theme, "sans", "active"),
|
||||
background: withOpacity(theme.backgroundColor[500].base, 0.8).value,
|
||||
background: withOpacity(theme.backgroundColor[500].base, 0.8),
|
||||
},
|
||||
notification: {
|
||||
margin: { top: 10 },
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import chroma, { Color, Scale } from "chroma-js";
|
||||
import { color, ColorToken, fontWeights, NumberToken } from "../../tokens";
|
||||
import { fontWeights, } from "../../common";
|
||||
import { withOpacity } from "../../utils/color";
|
||||
import Theme, { buildPlayer, Syntax } from "./theme";
|
||||
|
||||
@@ -26,10 +26,10 @@ export function createTheme(
|
||||
|
||||
let blend = isLight ? 0.12 : 0.24;
|
||||
|
||||
function sample(ramp: Scale, index: number): ColorToken {
|
||||
return color(ramp(index).hex());
|
||||
function sample(ramp: Scale, index: number): string {
|
||||
return ramp(index).hex();
|
||||
}
|
||||
const darkest = color(ramps.neutral(isLight ? 7 : 0).hex());
|
||||
const darkest = ramps.neutral(isLight ? 7 : 0).hex();
|
||||
|
||||
const backgroundColor = {
|
||||
// Title bar
|
||||
@@ -232,7 +232,7 @@ export function createTheme(
|
||||
};
|
||||
|
||||
const shadow = withOpacity(
|
||||
color(ramps.neutral(isLight ? 7 : 0).darken().hex()),
|
||||
ramps.neutral(isLight ? 7 : 0).darken().hex(),
|
||||
blend);
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
import { ColorToken, FontWeightToken, NumberToken } from "../../tokens";
|
||||
import { FontWeight } from "../../common";
|
||||
import { withOpacity } from "../../utils/color";
|
||||
|
||||
export interface SyntaxHighlightStyle {
|
||||
color: ColorToken;
|
||||
weight?: FontWeightToken;
|
||||
color: string;
|
||||
weight?: FontWeight;
|
||||
underline?: boolean;
|
||||
italic?: boolean;
|
||||
}
|
||||
|
||||
export interface Player {
|
||||
baseColor: ColorToken;
|
||||
cursorColor: ColorToken;
|
||||
selectionColor: ColorToken;
|
||||
borderColor: ColorToken;
|
||||
baseColor: string;
|
||||
cursorColor: string;
|
||||
selectionColor: string;
|
||||
borderColor: string;
|
||||
}
|
||||
export function buildPlayer(
|
||||
color: ColorToken,
|
||||
color: string,
|
||||
cursorOpacity?: number,
|
||||
selectionOpacity?: number,
|
||||
borderOpacity?: number
|
||||
@@ -29,9 +29,9 @@ export function buildPlayer(
|
||||
}
|
||||
|
||||
export interface BackgroundColorSet {
|
||||
base: ColorToken;
|
||||
hovered: ColorToken;
|
||||
active: ColorToken;
|
||||
base: string;
|
||||
hovered: string;
|
||||
active: string;
|
||||
}
|
||||
|
||||
export interface Syntax {
|
||||
@@ -81,64 +81,64 @@ export default interface Theme {
|
||||
info: BackgroundColorSet;
|
||||
};
|
||||
borderColor: {
|
||||
primary: ColorToken;
|
||||
secondary: ColorToken;
|
||||
muted: ColorToken;
|
||||
active: ColorToken;
|
||||
primary: string;
|
||||
secondary: string;
|
||||
muted: string;
|
||||
active: string;
|
||||
/**
|
||||
* Used for rendering borders on top of media like avatars, images, video, etc.
|
||||
*/
|
||||
onMedia: ColorToken;
|
||||
ok: ColorToken;
|
||||
error: ColorToken;
|
||||
warning: ColorToken;
|
||||
info: ColorToken;
|
||||
onMedia: string;
|
||||
ok: string;
|
||||
error: string;
|
||||
warning: string;
|
||||
info: string;
|
||||
};
|
||||
textColor: {
|
||||
primary: ColorToken;
|
||||
secondary: ColorToken;
|
||||
muted: ColorToken;
|
||||
placeholder: ColorToken;
|
||||
active: ColorToken;
|
||||
feature: ColorToken;
|
||||
ok: ColorToken;
|
||||
error: ColorToken;
|
||||
warning: ColorToken;
|
||||
info: ColorToken;
|
||||
onMedia: ColorToken;
|
||||
primary: string;
|
||||
secondary: string;
|
||||
muted: string;
|
||||
placeholder: string;
|
||||
active: string;
|
||||
feature: string;
|
||||
ok: string;
|
||||
error: string;
|
||||
warning: string;
|
||||
info: string;
|
||||
onMedia: string;
|
||||
};
|
||||
iconColor: {
|
||||
primary: ColorToken;
|
||||
secondary: ColorToken;
|
||||
muted: ColorToken;
|
||||
placeholder: ColorToken;
|
||||
active: ColorToken;
|
||||
feature: ColorToken;
|
||||
ok: ColorToken;
|
||||
error: ColorToken;
|
||||
warning: ColorToken;
|
||||
info: ColorToken;
|
||||
primary: string;
|
||||
secondary: string;
|
||||
muted: string;
|
||||
placeholder: string;
|
||||
active: string;
|
||||
feature: string;
|
||||
ok: string;
|
||||
error: string;
|
||||
warning: string;
|
||||
info: string;
|
||||
};
|
||||
editor: {
|
||||
background: ColorToken;
|
||||
indent_guide: ColorToken;
|
||||
indent_guide_active: ColorToken;
|
||||
background: string;
|
||||
indent_guide: string;
|
||||
indent_guide_active: string;
|
||||
line: {
|
||||
active: ColorToken;
|
||||
highlighted: ColorToken;
|
||||
active: string;
|
||||
highlighted: string;
|
||||
};
|
||||
highlight: {
|
||||
selection: ColorToken;
|
||||
occurrence: ColorToken;
|
||||
activeOccurrence: ColorToken;
|
||||
matchingBracket: ColorToken;
|
||||
match: ColorToken;
|
||||
activeMatch: ColorToken;
|
||||
related: ColorToken;
|
||||
selection: string;
|
||||
occurrence: string;
|
||||
activeOccurrence: string;
|
||||
matchingBracket: string;
|
||||
match: string;
|
||||
activeMatch: string;
|
||||
related: string;
|
||||
};
|
||||
gutter: {
|
||||
primary: ColorToken;
|
||||
active: ColorToken;
|
||||
primary: string;
|
||||
active: string;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -154,5 +154,5 @@ export default interface Theme {
|
||||
7: Player;
|
||||
8: Player;
|
||||
},
|
||||
shadow: ColorToken;
|
||||
shadow: string;
|
||||
}
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
import { colorRamp } from "./utils/color";
|
||||
|
||||
interface Token<V, T> {
|
||||
value: V,
|
||||
type: T
|
||||
}
|
||||
|
||||
export type FontFamily = string;
|
||||
export type FontFamilyToken = Token<FontFamily, "fontFamily">;
|
||||
function fontFamily(value: FontFamily): FontFamilyToken {
|
||||
return {
|
||||
value,
|
||||
type: "fontFamily"
|
||||
}
|
||||
}
|
||||
export const fontFamilies = {
|
||||
sans: fontFamily("Zed Sans"),
|
||||
mono: fontFamily("Zed Mono"),
|
||||
}
|
||||
|
||||
export type FontSize = number;
|
||||
export type FontSizeToken = Token<FontSize, "fontSize">;
|
||||
function fontSize(value: FontSize) {
|
||||
return {
|
||||
value,
|
||||
type: "fontSize"
|
||||
};
|
||||
}
|
||||
export const fontSizes = {
|
||||
"3xs": fontSize(8),
|
||||
"2xs": fontSize(10),
|
||||
xs: fontSize(12),
|
||||
sm: fontSize(14),
|
||||
md: fontSize(16),
|
||||
lg: fontSize(18),
|
||||
xl: fontSize(20),
|
||||
};
|
||||
|
||||
export type FontWeight =
|
||||
| "thin"
|
||||
| "extra_light"
|
||||
| "light"
|
||||
| "normal"
|
||||
| "medium"
|
||||
| "semibold"
|
||||
| "bold"
|
||||
| "extra_bold"
|
||||
| "black";
|
||||
export type FontWeightToken = Token<FontWeight, "fontWeight">;
|
||||
function fontWeight(value: FontWeight): FontWeightToken {
|
||||
return {
|
||||
value,
|
||||
type: "fontWeight"
|
||||
};
|
||||
}
|
||||
export const fontWeights = {
|
||||
"thin": fontWeight("thin"),
|
||||
"extra_light": fontWeight("extra_light"),
|
||||
"light": fontWeight("light"),
|
||||
"normal": fontWeight("normal"),
|
||||
"medium": fontWeight("medium"),
|
||||
"semibold": fontWeight("semibold"),
|
||||
"bold": fontWeight("bold"),
|
||||
"extra_bold": fontWeight("extra_bold"),
|
||||
"black": fontWeight("black"),
|
||||
}
|
||||
|
||||
// Standard size unit used for paddings, margins, borders, etc.
|
||||
|
||||
export type Size = number
|
||||
|
||||
export type SizeToken = Token<Size, "size">;
|
||||
function size(value: Size): SizeToken {
|
||||
return {
|
||||
value,
|
||||
type: "size"
|
||||
};
|
||||
}
|
||||
|
||||
export const sizes = {
|
||||
px: size(1),
|
||||
xs: size(2),
|
||||
sm: size(4),
|
||||
md: size(6),
|
||||
lg: size(8),
|
||||
xl: size(12),
|
||||
};
|
||||
|
||||
export type Color = string;
|
||||
export interface ColorToken {
|
||||
value: Color,
|
||||
type: "color",
|
||||
step?: number,
|
||||
}
|
||||
export function color(value: string): ColorToken {
|
||||
return {
|
||||
value,
|
||||
type: "color",
|
||||
};
|
||||
}
|
||||
export const colors = {
|
||||
neutral: colorRamp(["white", "black"], { steps: 37, increment: 25 }), // (900/25) + 1
|
||||
rose: colorRamp("#F43F5EFF"),
|
||||
red: colorRamp("#EF4444FF"),
|
||||
orange: colorRamp("#F97316FF"),
|
||||
amber: colorRamp("#F59E0BFF"),
|
||||
yellow: colorRamp("#EAB308FF"),
|
||||
lime: colorRamp("#84CC16FF"),
|
||||
green: colorRamp("#22C55EFF"),
|
||||
emerald: colorRamp("#10B981FF"),
|
||||
teal: colorRamp("#14B8A6FF"),
|
||||
cyan: colorRamp("#06BBD4FF"),
|
||||
sky: colorRamp("#0EA5E9FF"),
|
||||
blue: colorRamp("#3B82F6FF"),
|
||||
indigo: colorRamp("#6366F1FF"),
|
||||
violet: colorRamp("#8B5CF6FF"),
|
||||
purple: colorRamp("#A855F7FF"),
|
||||
fuschia: colorRamp("#D946E4FF"),
|
||||
pink: colorRamp("#EC4899FF"),
|
||||
}
|
||||
|
||||
export type NumberToken = Token<number, "number">;
|
||||
|
||||
export default {
|
||||
fontFamilies,
|
||||
fontSizes,
|
||||
fontWeights,
|
||||
size,
|
||||
colors,
|
||||
};
|
||||
@@ -1,52 +1,5 @@
|
||||
import chroma, { Scale } from "chroma-js";
|
||||
import { ColorToken } from "../tokens";
|
||||
import chroma from "chroma-js";
|
||||
|
||||
export type Color = string;
|
||||
export type ColorRampStep = { value: Color; type: "color"; description: string };
|
||||
export type ColorRamp = {
|
||||
[index: number]: ColorRampStep;
|
||||
};
|
||||
|
||||
export function colorRamp(
|
||||
color: Color | [Color, Color],
|
||||
options?: { steps?: number; increment?: number; }
|
||||
): ColorRamp {
|
||||
let scale: Scale;
|
||||
if (Array.isArray(color)) {
|
||||
const [startColor, endColor] = color;
|
||||
scale = chroma.scale([startColor, endColor]);
|
||||
} else {
|
||||
let hue = Math.round(chroma(color).hsl()[0]);
|
||||
let startColor = chroma.hsl(hue, 0.88, 0.96);
|
||||
let endColor = chroma.hsl(hue, 0.68, 0.12);
|
||||
scale = chroma
|
||||
.scale([startColor, color, endColor])
|
||||
.domain([0, 0.5, 1])
|
||||
.mode("hsl")
|
||||
.gamma(1)
|
||||
// .correctLightness(true)
|
||||
.padding([0, 0]);
|
||||
}
|
||||
|
||||
const ramp: ColorRamp = {};
|
||||
const steps = options?.steps || 10;
|
||||
const increment = options?.increment || 100;
|
||||
|
||||
scale.colors(steps, "hex").forEach((color, ix) => {
|
||||
const step = ix * increment;
|
||||
ramp[step] = {
|
||||
value: color,
|
||||
description: `Step: ${step}`,
|
||||
type: "color",
|
||||
};
|
||||
});
|
||||
|
||||
return ramp;
|
||||
}
|
||||
|
||||
export function withOpacity(color: ColorToken, opacity: number): ColorToken {
|
||||
return {
|
||||
...color,
|
||||
value: chroma(color.value).alpha(opacity).hex()
|
||||
};
|
||||
export function withOpacity(color: string, opacity: number): string {
|
||||
return chroma(color).alpha(opacity).hex();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user