Skip to content

Commit

Permalink
[gem-book] Add <gbp-content>
Browse files Browse the repository at this point in the history
  • Loading branch information
mantou132 committed Jan 18, 2024
1 parent d1e651b commit 0446219
Show file tree
Hide file tree
Showing 11 changed files with 117 additions and 42 deletions.
3 changes: 3 additions & 0 deletions packages/gem-book/docs/en/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ hero:
link: ./guide/README.md
features:
- title: Out of the box
icon: 📝
desc: Just run the command line to pack all front-end resources, so that all attention can be paid to document writing
- title: Performance
icon: /logo.png
desc: No redundant dependencies, the entire application will run smoothly with streamlined code
- title: Expandable
icon: 👩‍🎨
desc: Can insert custom elements into existing websites; using custom elements can also customize display documents very conveniently
---

Expand Down
15 changes: 15 additions & 0 deletions packages/gem-book/docs/zh/003-plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,21 @@ yarn add gem-book
<my-plugin-hello></my-plugin-hello>
```

## `<gbp-content>`

将内容插入 `<gem-book>`,这允许在特定页面自定义 `<gem-book>` 内容,例如自定义侧边栏:

```md
<gbp-content>
<div slot="sidebar-before">Test</div>
<style>
gem-book::part(sidebar-content) {
display: none;
}
</style>
</gbp-content>
```

## `<gbp-docsearch>`

使用 [Algolia DocSearch](https://docsearch.algolia.com/) 为网站提供搜索,只需要实例化一次,可以使用[插槽](./guide/007-extension.md#插槽)放在想要放置的位置:
Expand Down
3 changes: 3 additions & 0 deletions packages/gem-book/docs/zh/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ hero:
link: ./guide/README.md
features:
- title: 开箱即用
icon: 📝
desc: 只需运行一条命令就能构建所有前端资源,让所有注意力都能放在文档编写上。
- title: 高性能
icon: /logo.png
desc: 没有多余的依赖,整个应用将使用精简的代码流畅的运行。
- title: 可插拔可扩展
icon: 👩‍🎨
desc: 能将自定义元素插入已有的网站中;使用自定义元素也能非常方便的自定义展示文档。
---

Expand Down
15 changes: 10 additions & 5 deletions packages/gem-book/src/bin/builder.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'path';
import { writeFileSync, symlinkSync, renameSync } from 'fs';

import webpack, { DefinePlugin, Compilation, Compiler, sources } from 'webpack';
import webpack, { DefinePlugin, Compiler, sources } from 'webpack';
import serveStatic from 'serve-static';
import WebpackDevServer from 'webpack-dev-server';
import HtmlWebpackPlugin from 'html-webpack-plugin';
Expand Down Expand Up @@ -158,7 +158,7 @@ export async function build(dir: string, options: Required<CliUniqueConfig>, boo
devtool: debug && 'source-map',
plugins: [
new HtmlWebpackPlugin({
title: bookConfig.title || 'Gem-book App',
title: bookConfig.title || 'GemBook App',
...(template ? { template: path.resolve(process.cwd(), template) } : undefined),
// Automatically copied to the output directory
favicon: !isRemoteIcon && icon,
Expand All @@ -167,10 +167,15 @@ export async function build(dir: string, options: Required<CliUniqueConfig>, boo
},
}),
new DefinePlugin({
'import.meta.url': DefinePlugin.runtimeValue(({ module }) =>
// 插件 query 参数传递
'import.meta.url': DefinePlugin.runtimeValue(({ module }) => {
// 如果是符号链接返回的是原始路径
JSON.stringify(pluginRecord[module.resource]?.url),
),
const plugin =
pluginRecord[module.resource] ||
// 如果是 GemBook 本身 GEM_BOOK_DEV 模式,路径是 src
pluginRecord[module.resource.replace(/\/src\/plugins\/(\w*)\.ts/, '/plugins/$1.js')];
return JSON.stringify(plugin ? plugin.url : '');
}),
'process.env.DEV_MODE': !build,
'process.env.BOOK_CONFIG': JSON.stringify(bookConfig),
'process.env.THEME': JSON.stringify(await importObject(themePath)),
Expand Down
10 changes: 9 additions & 1 deletion packages/gem-book/src/bin/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,15 @@ export function getMetadata(fullPath: string, displayRank: boolean | undefined)
};
const parseMd = (fullPath: string) => {
const md = getMdFile(fullPath).content;
const { attributes, body } = fm<FrontMatter>(md);
let attributes: FrontMatter = {};
let body = '';
try {
const fmd = fm<FrontMatter>(md);
attributes = fmd.attributes;
body = fmd.body;
} catch {
print(chalk.red(`Parse frontmatter error: ${fullPath}`));
}
return {
...(attributes as FrontMatter),
title: parseTitle(attributes.title || load(marked(body))('h1').text() || getTitle()).text,
Expand Down
36 changes: 13 additions & 23 deletions packages/gem-book/src/element/elements/homepage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ export class Homepage extends GemElement {
<style>
.hero {
text-align: center;
padding: 3.5rem 1rem 5rem;
background-color: var(--background-color);
padding: 6rem 1rem;
}
.title {
margin: 0;
Expand All @@ -43,7 +42,7 @@ export class Homepage extends GemElement {
.actions {
display: flex;
flex-wrap: wrap;
margin: 2rem;
margin-block-start: 2rem;
gap: 1rem 2.5rem;
justify-content: center;
align-items: center;
Expand Down Expand Up @@ -74,9 +73,6 @@ export class Homepage extends GemElement {
transform: scale(1.3);
}
@media ${mediaQuery.PHONE} {
.hero {
padding: 2rem 1rem;
}
.title {
font-size: 2rem;
}
Expand Down Expand Up @@ -121,33 +117,31 @@ export class Homepage extends GemElement {
.feature,
.icon {
border-radius: ${theme.normalRound};
background-color: var(--background-color);
background-color: rgba(${theme.textColorRGB}, 0.03);
}
.feature {
padding: 1.5rem;
}
.icon {
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 2.5em;
display: grid;
place-items: center;
line-height: 1;
width: 30%;
aspect-ratio: 1;
padding: 0.5rem;
box-sizing: border-box;
margin-block-end: 2rem;
width: 3rem;
font-size: 2.4rem;
padding: 0.3rem;
margin-block-end: 1.5rem;
object-fit: contain;
}
.feat-title {
margin-block-end: 1rem;
font-size: 1.5em;
font-size: 1.15em;
font-weight: 500;
line-height: 1;
}
.feat-desc {
line-height: 1.5;
line-height: 1.7;
margin: 1rem 0 0;
letter-spacing: 0.05em;
opacity: 0.6;
}
@media ${mediaQuery.DESKTOP} {
Expand All @@ -163,9 +157,6 @@ export class Homepage extends GemElement {
.features .body {
grid-template-columns: auto;
}
.icon {
width: 5rem;
}
.feat-title,
.feat-desc {
margin: 0;
Expand All @@ -179,7 +170,7 @@ export class Homepage extends GemElement {
<div class="feature ${feature.icon ? 'has-icon' : ''}">
${!feature.icon
? ''
: [...feature.icon].length === 1
: [...feature.icon].length <= 3
? html`<span class="icon">${feature.icon}</span>`
: html`<img
class="icon"
Expand Down Expand Up @@ -211,7 +202,6 @@ export class Homepage extends GemElement {
<style>
:host {
overflow: hidden;
--background-color: color-mix(in srgb, ${theme.textColor} 3%, ${theme.primaryColor} 2%);
}
.body {
margin: auto;
Expand Down
11 changes: 9 additions & 2 deletions packages/gem-book/src/element/elements/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
useStore,
refobject,
RefObject,
part,
} from '@mantou/gem';
import { mediaQuery } from '@mantou/gem/helper/mediaquery';

Expand All @@ -33,6 +34,9 @@ export const [sidebarStore, updateSidebarStore] = useStore({ open: false });
@connectStore(sidebarStore)
@connectStore(tocStore)
export class SideBar extends GemElement {
@part static content: string;
@part static logo: string;

@refobject navRef: RefObject<HTMLElement>;

@state open: boolean;
Expand Down Expand Up @@ -66,6 +70,9 @@ export class SideBar extends GemElement {
if (sidebarIgnore || (homeMode && homePage === link)) {
return html`<!-- No need to render homepage item -->`;
}
if (!title && !bookStore.isDevMode) {
return html``;
}
switch (type) {
case 'dir': {
if (!children?.length) {
Expand Down Expand Up @@ -268,7 +275,7 @@ export class SideBar extends GemElement {
}
}
</style>
<gem-book-nav-logo>
<gem-book-nav-logo part=${SideBar.logo}>
<slot name="logo-after"></slot>
</gem-book-nav-logo>
<div class="nav" ref=${this.navRef.ref}>
Expand All @@ -286,7 +293,7 @@ export class SideBar extends GemElement {
`
: ''}
<slot></slot>
${bookStore.currentSidebar?.map((item) => this.#renderItem(item, true))}
<div part=${SideBar.content}>${bookStore.currentSidebar?.map((item) => this.#renderItem(item, true))}</div>
</div>
`;
}
Expand Down
23 changes: 19 additions & 4 deletions packages/gem-book/src/element/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
refobject,
RefObject,
boolattribute,
exportPartsMap,
} from '@mantou/gem';
import { GemLightRouteElement, matchPath } from '@mantou/gem/elements/route';
import { mediaQuery } from '@mantou/gem/helper/mediaquery';
Expand All @@ -27,12 +28,12 @@ import { checkBuiltInPlugin, joinPath } from './lib/utils';
import { GemBookPluginElement } from './elements/plugin';
import { Loadbar } from './elements/loadbar';
import { Homepage } from './elements/homepage';
import { SideBar } from './elements/sidebar';
import type { Main } from './elements/main';

import '@mantou/gem/elements/title';
import '@mantou/gem/elements/reflect';
import './elements/nav';
import './elements/sidebar';
import './elements/footer';
import './elements/edit-link';
import './elements/rel-link';
Expand Down Expand Up @@ -68,6 +69,8 @@ export class GemBookElement extends GemElement {
@part static relLink: string;
@part static footer: string;
@part static homepageHero: string;
@part static sidebarContent: string;
@part static sidebarLogo: string;

@slot static sidebarBefore: string;
@slot static mainBefore: string;
Expand Down Expand Up @@ -208,7 +211,6 @@ export class GemBookElement extends GemElement {
@media ${renderFullWidth ? 'all' : 'not all'} {
gem-book-nav {
grid-area: 1 / aside / 2 / toc;
box-shadow: 0 0 1.5rem #00000015;
}
gem-book-homepage,
main {
Expand Down Expand Up @@ -268,14 +270,27 @@ export class GemBookElement extends GemElement {
: null}
${mediaQuery.isPhone || !renderFullWidth
? html`
<gem-book-sidebar role="navigation" part=${GemBookElement.sidebar}>
<gem-book-sidebar
role="navigation"
exportparts=${exportPartsMap({
[SideBar.content]: GemBookElement.sidebarContent,
[SideBar.logo]: GemBookElement.sidebarLogo,
})}
part=${GemBookElement.sidebar}
>
<slot slot=${GemBookElement.logoAfter} name=${GemBookElement.logoAfter}></slot>
<slot name=${GemBookElement.sidebarBefore}></slot>
</gem-book-sidebar>
`
: null}
${renderHomePage
? html`<gem-book-homepage exportparts="${Homepage.hero}: ${GemBookElement.homepageHero}"></gem-book-homepage>`
? html`
<gem-book-homepage
exportparts=${exportPartsMap({
[Homepage.hero]: GemBookElement.homepageHero,
})}
></gem-book-homepage>
`
: ''}
<main>
${renderHomePage ? '' : html`<slot name=${GemBookElement.mainBefore}></slot>`}
Expand Down
20 changes: 20 additions & 0 deletions packages/gem-book/src/plugins/content.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { GemBookElement } from '../element';

customElements.whenDefined('gem-book').then(({ GemBookPluginElement }: typeof GemBookElement) => {
const { Gem } = GemBookPluginElement;
const { customElement, html, attribute } = Gem;

@customElement('gbp-content')
class _GbpContentElement extends GemBookPluginElement {
@attribute method: 'prepend' | 'append';

render() {
const bookEle = document.querySelector('gem-book');
return html`
<gem-reflect .method=${this.method} .target=${bookEle}>
${[...this.children].map((e) => e.cloneNode(true))}
</gem-reflect>
`;
}
}
});
21 changes: 15 additions & 6 deletions packages/gem/src/elements/base/reflect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* 比如 duoyun-ui 文档站加载示例元素时把 GemReflectElement 渲染的元素清除
*/
import { GemElement } from '../../lib/element';
import { property } from '../../lib/decorators';
import { attribute, property } from '../../lib/decorators';

const START = 'gem-reflect-start';
const END = 'gem-reflect-end';
Expand All @@ -26,8 +26,14 @@ const getReflectFragment = (startNode: Comment) => {
};

export class GemReflectElement extends GemElement {
@attribute method: 'prepend' | 'append';

@property target: HTMLElement = document.head;

get #method() {
return this.method || 'append';
}

constructor() {
super({ isLight: true });

Expand All @@ -45,11 +51,14 @@ export class GemReflectElement extends GemElement {

this.effect(
() => {
if (!childNodes) {
[startNode, ...this.childNodes, endNode].forEach((node) => this.target.append(node));
} else {
childNodes.forEach((node) => this.target.append(node));
}
(childNodes || [startNode, ...this.childNodes, endNode]).forEach((node, index, arr) => {
const prev = arr[index - 1];
if (prev) {
prev.after(node);
} else {
this.target[this.#method](node);
}
});
return () => {
childNodes = getReflectFragment(startNode);
childNodes.forEach((node) => node.remove());
Expand Down
2 changes: 1 addition & 1 deletion packages/gem/src/elements/base/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ export class GemRouteElement extends GemElement<State> {

constructor({ isLight, routes }: ConstructorOptions = {}) {
super({ isLight });
this.routes = routes;
this.routes = this.routes || routes;
}

state: State = {
Expand Down

0 comments on commit 0446219

Please sign in to comment.