Skip to content

Commit

Permalink
feat: 🎸 add theme plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
Saul-Mirone authored Aug 16, 2021
1 parent c1d0a24 commit 1feda21
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 2 deletions.
2 changes: 2 additions & 0 deletions packages/core/src/editor/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
nodeView,
editorState,
commands,
theme,
} from '../internal-plugin';
import { createClock, Timer } from '../timing';
import { Configure, Ctx, CtxHandler, MilkdownPlugin, Pre } from '../utility';
Expand Down Expand Up @@ -63,6 +64,7 @@ export class Editor {

#loadInternal = () => {
const internalPlugins = [
theme,
schema,
parser,
serializer,
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/internal-plugin/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './init';
export * from './config';
export * from './theme';

export * from './schema';
export * from './parser';
Expand Down
84 changes: 84 additions & 0 deletions packages/core/src/internal-plugin/theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { MilkdownPlugin } from '../utility';
import { createCtx } from '../context';
import { Config } from './config';

type PR<K extends string, V = string> = Partial<Record<K, V>>;

const themeColor = (hex: string) => {
const hex2rgb = (hex: string) => {
const rgbShorthandRegex = /^([a-f\d])([a-f\d])([a-f\d])$/i;
const rgbRegex = /^([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;
const parse16 = (x: string) => parseInt(x, 16);

const fullHex = hex.slice(1).replace(rgbShorthandRegex, (_, r, g, b) => {
return r + r + g + g + b + b;
});

const [ok, r, g, b] = fullHex.match(rgbRegex) || [];

return ok ? [r, g, b].map(parse16) : null;
};

const rgb = hex2rgb(hex);
if (!rgb) {
console.warn(`Invalid hex: ${hex}`);
return hex;
}

return rgb.join(', ');
};

export type Color = 'neutral' | 'solid' | 'shadow' | 'primary' | 'secondary' | 'line' | 'background' | 'surface';

export type Font = 'font' | 'fontCode';

export type Size = 'radius' | 'lineWidth';

export type Widget = 'icon' | 'scrollbar' | 'shadow' | 'border';

export type ThemePack = {
color?: { light?: PR<Color>; dark?: PR<Color> } & PR<Color>;
font?: PR<Font, string[]>;
size?: PR<Size>;
widget?: PR<Widget, string>;
};

export type ThemeTool = {
size: Partial<Record<Size, string>>;
widget: Partial<Record<Widget, string>>;
palette: (key: Color, alpha: number) => string;
fonts: (key: Font) => string;
};
export const themeToolCtx = createCtx<ThemeTool>({
size: {},
widget: {},
fonts: () => '',
palette: () => '',
});
export const themePackCtx = createCtx<ThemePack>({});
export const isDarkCtx = createCtx(false);

export const theme: MilkdownPlugin = (pre) => {
pre.inject(themeToolCtx).inject(isDarkCtx).inject(themePackCtx, {});
return async (ctx) => {
await ctx.wait(Config);
const isDark = ctx.get(isDarkCtx);
const themePack = ctx.get(themePackCtx);
const { color, font, size = {}, widget = {} } = themePack;
const palette = (key: Color, alpha: number) => {
const value = color?.[isDark ? 'dark' : 'light']?.[key] ?? color?.[key];
return value ? `rgba(${themeColor(value)}, ${alpha})` : '';
};
const fonts = (key: Font) => {
const value = font?.[key] ?? [];
return value.join(', ');
};

ctx.set(themeToolCtx, {
size,
widget,
palette,
fonts,
});
};
};
11 changes: 9 additions & 2 deletions packages/theme-nord/package.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
{
"name": "@milkdown/theme-nord",
"version": "4.9.6",
"main": "lib/index.js",
"module": "lib/index.js",
"types": "lib/index.d.ts",
"license": "MIT",
"scripts": {
"start": "vite",
"watch": "postcss style/theme.css --watch --verbose -o lib/theme.css",
"watch": "concurrently -n ts,css \"tsc -w\" \"postcss style/theme.css --watch --verbose -o lib/theme.css\"",
"watch:css": "postcss style/theme.css --watch --verbose -o lib/theme.css",
"build": "postcss style/theme.css -o lib/theme.css",
"tsc": "tsc --noEmit",
"build": "tsc && postcss style/theme.css --verbose -o lib/theme.css",
"build:css": "postcss style/theme.css --verbose -o lib/theme.css"
},
"devDependencies": {
"@milkdown/design-system": "workspace:*"
},
"peerDependencies": {
"@milkdown/core": "*"
},
"files": [
"lib"
],
Expand Down
59 changes: 59 additions & 0 deletions packages/theme-nord/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import type { ThemePack } from '@milkdown/core';

const font = [
'Roboto',
'HelveticaNeue-Light',
'Helvetica Neue Light',
'Helvetica Neue',
'Helvetica',
'Arial',
'Lucida Grande',
'sans-serif',
];

const fontCode = ['Consolas', 'Monaco', 'Andale Mono', 'Ubuntu Mono', 'monospace'];

export const Nord = {
nord0: '#2e3440',
nord1: '#3b4252',
nord2: '#434c5e',
nord3: '#4c566a',
nord4: '#d8dee9',
nord5: '#e5e9f0',
nord6: '#eceff4',
nord7: '#8fbcbb',
nord8: '#88c0d0',
nord9: '#81a1c1',
nord10: '#5e81ac',
nord11: '#bf616a',
nord12: '#d08770',
nord13: '#ebcb8b',
nord14: '#a3be8c',
nord15: '#b48ead',
};

export const nord: ThemePack = {
font: {
font,
fontCode,
},
color: {
shadow: Nord.nord1,
primary: Nord.nord10,
secondary: Nord.nord9,
light: {
neutral: Nord.nord0,
solid: Nord.nord3,
line: Nord.nord4,
background: Nord.nord6,
surface: '#fff',
},
dark: {
neutral: Nord.nord6,
solid: Nord.nord4,
line: Nord.nord2,
background: '#252932',
surface: Nord.nord0,
},
},
};
11 changes: 11 additions & 0 deletions packages/theme-nord/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "lib"
},
"include": ["src"],
"references": [
{ "path": "../core" },
]
}
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
{ "path": "./packages/exception" },
{ "path": "./packages/react" },
{ "path": "./packages/vue" },
{ "path": "./packages/theme-nord" },
{ "path": "./packages/preset-commonmark" },
{ "path": "./packages/preset-gfm" },
{ "path": "./packages/design-system" },
Expand Down

0 comments on commit 1feda21

Please sign in to comment.