Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffwcx committed Jan 3, 2024
2 parents 6f39fa1 + 1865b01 commit ac81c9d
Show file tree
Hide file tree
Showing 16 changed files with 135 additions and 38 deletions.
3 changes: 3 additions & 0 deletions .dumi/theme/slots/HeaderExtra/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ const HeaderExtra: FC = () => {
window.open('https://v1.d.umijs.org/', '_blank');
}
}}
onClick={(e) => {
e.stopPropagation();
}}
>
<option value={process.env.DUMI_VERSION}>
{process.env.DUMI_VERSION}
Expand Down
4 changes: 2 additions & 2 deletions docs/config/runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ group: 框架配置

## 配置项

### modifyCodeSandBoxData
### modifyCodeSandboxData

修改在 CodeSandbox 中打开 demo 的数据,比如修改依赖、增加文件等。

```js
export function modifyCodeSandBoxData(memo, props) {
export function modifyCodeSandboxData(memo, props) {
// 根据需要修改 memo 并返回新值
return memo;
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dumi",
"version": "2.2.14",
"version": "2.2.16",
"description": "📖 Documentation Generator of React Component",
"keywords": [
"generator",
Expand Down
7 changes: 4 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions src/client/theme-api/usePrefersColor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,15 @@ class ColorChanger {
* listen color change
* @param cb callback
*/
listen(cb: typeof this.callbacks[number]) {
listen(cb: (typeof this.callbacks)[number]) {
this.callbacks.push(cb);
}

/**
* unlisten color change
* @param cb callback
*/
unlisten(cb: typeof this.callbacks[number]) {
unlisten(cb: (typeof this.callbacks)[number]) {
this.callbacks.splice(this.callbacks.indexOf(cb), 1);
}

Expand All @@ -108,7 +108,7 @@ class ColorChanger {
this.prefersColor = color;
this.color =
color === 'auto' ? (this.isColorMode('dark') ? 'dark' : 'light') : color;
document.documentElement.setAttribute(PREFERS_COLOR_ATTR, color);
document.documentElement.setAttribute(PREFERS_COLOR_ATTR, this.color);
this.applyCallbacks();

return color;
Expand Down
1 change: 1 addition & 0 deletions src/client/theme-default/slots/ColorSwitch/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const ColorSwitch: FC = () => {
<select
onChange={(ev) => setPrefersColor(ev.target.value as any)}
value={prefersColor}
onClick={(e) => e.stopPropagation()}
>
{['light', 'dark', 'auto'].map((c) => (
<option value={c} key={c}>
Expand Down
3 changes: 3 additions & 0 deletions src/client/theme-default/slots/SearchBar/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@
background-color: @c-site-bg-dark;
box-shadow: 0 0 0 3px fade(@c-primary-dark, 10%);
}
}

&:focus,
&:not(:placeholder-shown) {
~ .@{prefix}-search-shortcut {
opacity: 0;
}
Expand Down
27 changes: 24 additions & 3 deletions src/client/theme-default/slots/SearchResult/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { ReactComponent as IconInbox } from '@ant-design/icons-svg/inline-svg/outlined/inbox.svg';
import { FormattedMessage, history, Link, type useSiteSearch } from 'dumi';
import animateScrollTo from 'animated-scroll-to';
import {
FormattedMessage,
history,
Link,
useLocation,
type useSiteSearch,
} from 'dumi';
import React, {
Fragment,
useCallback,
Expand Down Expand Up @@ -119,6 +126,20 @@ const SearchResult: FC<{
}> = (props) => {
const [data, histsCount] = useFlatSearchData(props.data);
const [activeIndex, setActiveIndex] = useState(-1);
const { pathname } = useLocation();

const onItemSelect = (item: ISearchResult[0]['hints'][0]) => {
props.onItemSelect?.(item);

const url = new URL(item?.link, location.origin);
if (url?.pathname === pathname && !url.hash) {
setTimeout(() => {
animateScrollTo(0, {
maxDuration: 300,
});
}, 1);
}
};

useEffect(() => {
const handler = (ev: KeyboardEvent) => {
Expand All @@ -133,7 +154,7 @@ const SearchResult: FC<{
)!.value as ISearchResult[0]['hints'][0];

history.push(item.link);
props.onItemSelect?.(item);
onItemSelect?.(item);
(document.activeElement as HTMLInputElement).blur();
}

Expand Down Expand Up @@ -167,7 +188,7 @@ const SearchResult: FC<{
<Link
to={item.value.link}
data-active={activeIndex === item.activeIndex || undefined}
onClick={() => props.onItemSelect?.(item.value)}
onClick={() => onItemSelect?.(item.value)}
>
{React.createElement(ICONS_MAPPING[item.value.type])}
<h4>
Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ export const VERSION_2_LEVEL_NAV = '^2.2.0';
export const VERSION_2_DEPRECATE_SOFT_BREAKS = '^2.2.0';

export const DEFAULT_DEMO_EXTENSIONS = ['.js', '.jsx', '.ts', '.tsx'];
export const FS_CACHE_DIR = 'node_modules/.cache/dumi';
29 changes: 20 additions & 9 deletions src/features/compile/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import type { IDemoLoaderOptions } from '@/loaders/demo';
import type { IMdLoaderOptions } from '@/loaders/markdown';
import ReactTechStack from '@/techStacks/react';
import type { IApi, IDumiTechStack } from '@/types';
import { _setFSCacheDir } from '@/utils';
import path from 'path';
import { addAtomMeta, addExampleAssets } from '../assets';

export default (api: IApi) => {
Expand All @@ -14,17 +16,26 @@ export default (api: IApi) => {
fn: () => new ReactTechStack(),
});

// add customize option for babel-loader, to avoid collect wrong deps result in MFSU
api.modifyConfig((memo) => {
if (memo.babelLoaderCustomize) {
api.logger.warn(
'Config `babelLoaderCustomize` will be override by dumi, please report issue if you need it.',
);
}
api.modifyConfig({
stage: Infinity,
fn: (memo) => {
// add customize option for babel-loader, to avoid collect wrong deps result in MFSU
if (memo.babelLoaderCustomize) {
api.logger.warn(
'Config `babelLoaderCustomize` will be override by dumi, please report issue if you need it.',
);
}

memo.babelLoaderCustomize = require.resolve('./babelLoaderCustomize');
memo.babelLoaderCustomize = require.resolve('./babelLoaderCustomize');

return memo;
// configure dumi fs cache dir
const cacheDirPath =
api.userConfig.cacheDirectoryPath || memo.cacheDirectoryPath;

if (cacheDirPath) _setFSCacheDir(path.join(cacheDirPath, 'dumi'));

return memo;
},
});

// configure loader to compile markdown
Expand Down
41 changes: 39 additions & 2 deletions src/features/parser.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,53 @@
import type { AtomAssetsParser, IApi } from '@/types';
import { lodash } from '@umijs/utils';
import assert from 'assert';
import { BaseAtomAssetsParser } from '../assetParsers/BaseParser';
import { ATOMS_META_PATH } from './meta';

type IParsedAtomAssets = Awaited<ReturnType<AtomAssetsParser['parse']>>;

function filterIgnoredProps(
props: IParsedAtomAssets['components'][string]['propsConfig']['properties'],
) {
return lodash.pickBy(props, (prop) => {
let isHidden = false;

if (prop.type === 'array' && 'items' in prop) {
prop.items = filterIgnoredProps({ _: prop.items! })._;
} else if (prop.type === 'object' && 'properties' in prop) {
prop.properties = filterIgnoredProps(prop.properties!);
} else if (prop.oneOf) {
// oneOf may be [null] with unknown reason
prop.oneOf = prop.oneOf
.filter(Boolean)
.map((item) => filterIgnoredProps({ _: item })._);
} else if (prop.allOf) {
// allOf may be [null] with unknown reason
prop.allOf = prop.allOf
.filter(Boolean)
.map((item) => filterIgnoredProps({ _: item })._);
} else if ('hidden' in prop) {
isHidden = true;
}

return !isHidden;
});
}

export default (api: IApi) => {
let prevData: Awaited<ReturnType<AtomAssetsParser['parse']>>;
let prevData: IParsedAtomAssets;
const writeAtomsMetaFile = (data: typeof prevData) => {
// filter ignored properties
const components = lodash.mapValues(data.components, (component) => ({
...component,
propsConfig: filterIgnoredProps({ _: component.propsConfig })._,
}));

api.writeTmpFile({
noPluginDir: true,
path: ATOMS_META_PATH,
content: `export const components = ${JSON.stringify(
data.components,
components,
null,
2,
)};`,
Expand Down
29 changes: 17 additions & 12 deletions src/features/theme/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
VERSION_2_LEVEL_NAV,
} from '@/constants';
import type { IApi } from '@/types';
import { parseModuleSync } from '@umijs/bundler-utils';
import { parseModule } from '@umijs/bundler-utils';
import { execSync } from 'child_process';
import fs from 'fs';
import hostedGit from 'hosted-git-info';
Expand Down Expand Up @@ -67,11 +67,13 @@ function getPkgThemePath(api: IApi) {
/**
* get exports for module
*/
function getModuleExports(modulePath: string) {
return parseModuleSync({
async function getModuleExports(modulePath: string) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_, exports] = await parseModule({
path: modulePath,
content: fs.readFileSync(modulePath, 'utf-8'),
})[1];
});
return exports || [];
}

/**
Expand Down Expand Up @@ -329,16 +331,17 @@ export default DumiLoading;
},
});

api.onGenerateFiles(() => {
api.onGenerateFiles(async () => {
// write shadow theme files to tmp dir
themeMapKeys.forEach((key) => {
Object.values(originalThemeData[key] || {}).forEach((item) => {
const pAll = themeMapKeys.flatMap((key) =>
Object.values(originalThemeData[key] || {}).map(async (item) => {
// skip write internal components
if (item.source === 'dumi') return;

let contents = [];
// parse exports for theme module
const exports = getModuleExports(item.source);
const exports = await getModuleExports(item.source);

const contents = [];

// export default
if (exports.includes('default')) {
Expand All @@ -355,13 +358,15 @@ export default DumiLoading;
path: `dumi/theme/${key}/${item.specifier}.ts`,
content: contents.join('\n'),
});
});
});
}),
);

await Promise.all(pAll);

const entryFile =
api.config.resolve.entryFile &&
[path.resolve(api.cwd, api.config.resolve.entryFile)].find(fs.existsSync);
const entryExports = entryFile ? getModuleExports(entryFile) : [];
const entryExports = entryFile ? await getModuleExports(entryFile) : [];
const hasDefaultExport = entryExports.includes('default');
const hasNamedExport = entryExports.some((exp) => exp !== 'default');

Expand Down
6 changes: 6 additions & 0 deletions src/loaders/markdown/transformer/fixtures/embed/embed.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,9 @@
second line

third line

type:null

:::success
这是一条成功信息
:::
4 changes: 3 additions & 1 deletion src/loaders/markdown/transformer/fixtures/embed/expect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { IMdTransformerResult } from '../..';

export default (ret: IMdTransformerResult) => {
expect(ret.content).toEqual(
'<><div className="markdown"><h3 id="this-is-indexmd"><a aria-hidden="true" tabIndex="-1" href="#this-is-indexmd"><span className="icon icon-link" /></a>{"This is index.md"}</h3><h3 id="this-is-embedmd"><a aria-hidden="true" tabIndex="-1" href="#this-is-embedmd"><span className="icon icon-link" /></a>{"This is embed.md"}</h3><p>{$$contentTexts[0].value}</p><p>{$$contentTexts[1].value}</p><h3 id="this-is-embedmd-1"><a aria-hidden="true" tabIndex="-1" href="#this-is-embedmd-1"><span className="icon icon-link" /></a>{"This is embed.md"}</h3><h3 id="this-is-embedmd-2"><a aria-hidden="true" tabIndex="-1" href="#this-is-embedmd-2"><span className="icon icon-link" /></a>{"This is embed.md"}</h3><p>{$$contentTexts[2].value}</p><h3 id="this-is-embedmd-3"><a aria-hidden="true" tabIndex="-1" href="#this-is-embedmd-3"><span className="icon icon-link" /></a>{"This is embed.md"}</h3><p>{$$contentTexts[3].value}</p><p>{$$contentTexts[4].value}</p><h3 id="this-is-embedmd-4"><a aria-hidden="true" tabIndex="-1" href="#this-is-embedmd-4"><span className="icon icon-link" /></a>{"This is embed.md"}</h3><p>{$$contentTexts[5].value}</p><p>{$$contentTexts[6].value}</p></div></>',
'<><div className="markdown"><h3 id="this-is-indexmd"><a aria-hidden="true" tabIndex="-1" href="#this-is-indexmd"><span className="icon icon-link" /></a>{"This is index.md"}</h3><h3 id="this-is-embedmd"><a aria-hidden="true" tabIndex="-1" href="#this-is-embedmd"><span className="icon icon-link" /></a>{"This is embed.md"}</h3><p>{$$contentTexts[0].value}</p><p>{$$contentTexts[1].value}</p><p>{$$contentTexts[2].value}</p></div><Container type="success"><p>{$$contentTexts[3].value}</p></Container><div className="markdown"><h3 id="this-is-embedmd-1"><a aria-hidden="true" tabIndex="-1" href="#this-is-embedmd-1"><span className="icon icon-link" /></a>{"This is embed.md"}</h3><h3 id="this-is-embedmd-2"><a aria-hidden="true" tabIndex="-1" href="#this-is-embedmd-2"><span className="icon icon-link" /></a>{"This is embed.md"}</h3><p>{$$contentTexts[4].value}</p><h3 id="this-is-embedmd-3"><a aria-hidden="true" tabIndex="-1" href="#this-is-embedmd-3"><span className="icon icon-link" /></a>{"This is embed.md"}</h3><p>{$$contentTexts[5].value}</p><p>{$$contentTexts[6].value}</p><p>{$$contentTexts[7].value}</p></div><Container type="success"><p>{$$contentTexts[8].value}</p></Container><div className="markdown"><h3 id="this-is-embedmd-4"><a aria-hidden="true" tabIndex="-1" href="#this-is-embedmd-4"><span className="icon icon-link" /></a>{"This is embed.md"}</h3><p>{$$contentTexts[9].value}</p><p>{$$contentTexts[10].value}</p><p>{$$contentTexts[11].value}</p></div><Container type="success"><p>{$$contentTexts[12].value}</p></Container></>',
);

expect(ret.meta.texts?.[2].value).toEqual('type:null');
};
2 changes: 2 additions & 0 deletions src/loaders/markdown/transformer/remarkEmbed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { winPath } from 'umi/plugin-utils';
import type { FrozenProcessor, Transformer } from 'unified';
import url from 'url';
import type { IMdTransformerOptions } from '.';
import remarkContainer from './remarkContainer';

const EMBED_OPEN_TAG = '<embed ';
const EMBED_CLOSE_TAG = '</embed>';
Expand Down Expand Up @@ -150,6 +151,7 @@ export default function remarkEmbed(
// because directive & gfm is affect on micromark core parser rather than ast
// and if they are not applied, the embed ast will be wrong
.use(remarkDirective)
.use(remarkContainer)
.use(remarkGfm)
// for update relative src path
.use(remarkReplaceSrc, {
Expand Down
8 changes: 6 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import fs from 'fs';
import yaml from 'js-yaml';
import path from 'path';
import { lodash, logger, winPath } from 'umi/plugin-utils';
import { FS_CACHE_DIR } from './constants';

/**
* get route path from file-system path
Expand Down Expand Up @@ -81,14 +82,17 @@ export function parseCodeFrontmatter(raw: string) {
/**
* get file-system cache for specific namespace
*/
let cacheDir = FS_CACHE_DIR;
const caches: Record<string, ReturnType<typeof Cache>> = {};
const CACHE_PATH = 'node_modules/.cache/dumi';
export function _setFSCacheDir(dir: string) {
cacheDir = dir;
}
export function getCache(ns: string): (typeof caches)['0'] {
// return fake cache if cache disabled
if (process.env.DUMI_CACHE === 'none') {
return { set() {}, get() {}, setSync() {}, getSync() {} } as any;
}
return (caches[ns] ??= Cache({ basePath: path.join(CACHE_PATH, ns) }));
return (caches[ns] ??= Cache({ basePath: path.resolve(cacheDir, ns) }));
}

/**
Expand Down

0 comments on commit ac81c9d

Please sign in to comment.