init
This commit is contained in:
commit
c5b43c67f2
23 changed files with 3413 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
node_modules/
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2023 sup39
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
2
README.md
Normal file
2
README.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
# supMDX-page
|
||||
Page component for supMDX
|
9
dist/Footer.d.ts
vendored
Normal file
9
dist/Footer.d.ts
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
export type FooterConfig = {
|
||||
site: {
|
||||
startYear?: number;
|
||||
author: string;
|
||||
};
|
||||
};
|
||||
export declare function Footer({ config }: {
|
||||
config: FooterConfig;
|
||||
}): JSX.Element;
|
38
dist/MDXPage.d.ts
vendored
Normal file
38
dist/MDXPage.d.ts
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
import { NavHeaderConfig } from '@sup39/mdx-nav';
|
||||
import { I18N, LocaleInfo } from './i18n';
|
||||
import { I18NNavEntryInfo } from './i18n-nav';
|
||||
type HeadingInfo = {
|
||||
tagName: string;
|
||||
label: string;
|
||||
id: string;
|
||||
};
|
||||
export type MDXProps = {
|
||||
children: JSX.Element;
|
||||
router: {
|
||||
pathname: string;
|
||||
} & LocaleInfo;
|
||||
meta: Partial<{
|
||||
title: I18N<string>;
|
||||
description: I18N<string>;
|
||||
h1: I18N<string>;
|
||||
[key: string]: any;
|
||||
}>;
|
||||
headings: HeadingInfo[];
|
||||
config: MDXConfig;
|
||||
};
|
||||
export type MDXConfig = {
|
||||
site: {
|
||||
startYear?: number;
|
||||
author: string;
|
||||
title: I18N<string>;
|
||||
subtitle?: I18N<string>;
|
||||
} & Omit<NavHeaderConfig, 'title' | 'subtitle'>;
|
||||
metaFields?: {
|
||||
label: I18N<string>;
|
||||
attr: string;
|
||||
}[];
|
||||
nav: I18NNavEntryInfo[];
|
||||
};
|
||||
export declare function MDXPageBase({ children, router, meta: meta18, headings, config, }: MDXProps): JSX.Element;
|
||||
export declare const MDXPageFactory: (config: MDXConfig) => ({ children, ...props }: Omit<MDXProps, 'config'>) => JSX.Element;
|
||||
export {};
|
8
dist/MetaInfo.d.ts
vendored
Normal file
8
dist/MetaInfo.d.ts
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
export type MetaInfoProps = {
|
||||
data: Record<string, any>;
|
||||
fields: {
|
||||
label: string;
|
||||
attr: string;
|
||||
}[];
|
||||
};
|
||||
export declare function MetaInfo({ fields, data }: MetaInfoProps): JSX.Element;
|
8
dist/i18n-nav.d.ts
vendored
Normal file
8
dist/i18n-nav.d.ts
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
import type { NavEntryInfo } from '@sup39/mdx-nav';
|
||||
import { I18N, translate } from './i18n';
|
||||
export type I18NNavEntryInfo = {
|
||||
label: I18N<string>;
|
||||
link: string;
|
||||
children?: I18NNavEntryInfo[];
|
||||
};
|
||||
export declare function translateNav(nav18: I18NNavEntryInfo[], localeInfo: Parameters<typeof translate>[1]): NavEntryInfo[];
|
9
dist/i18n.d.ts
vendored
Normal file
9
dist/i18n.d.ts
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
export type NonRecordType = boolean | number | bigint | string | symbol | any[];
|
||||
export type I18N<T> = (T & NonRecordType) | Record<string, T>;
|
||||
export type LocaleInfo = {
|
||||
locale?: string;
|
||||
defaultLocale?: string;
|
||||
};
|
||||
export declare function translate<T>(data: I18N<T>, { locale, defaultLocale }: LocaleInfo): T;
|
||||
export declare function translate<T>(data: I18N<T> | null, { locale, defaultLocale }: LocaleInfo): null;
|
||||
export declare function translate<T>(data: I18N<T> | undefined, { locale, defaultLocale }: LocaleInfo): undefined;
|
5
dist/index.d.ts
vendored
Normal file
5
dist/index.d.ts
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
export * from './Footer';
|
||||
export * from './MDXPage';
|
||||
export * from './MetaInfo';
|
||||
export * from './i18n';
|
||||
export * from './i18n-nav';
|
218
dist/index.esm.js
vendored
Normal file
218
dist/index.esm.js
vendored
Normal file
|
@ -0,0 +1,218 @@
|
|||
import React, { useState } from 'react';
|
||||
import Head from 'next/head';
|
||||
import Link from 'next/link';
|
||||
|
||||
function Footer(_a) {
|
||||
var config = _a.config;
|
||||
var year = new Date().getFullYear();
|
||||
var _b = config.site, _c = _b.startYear, year0 = _c === void 0 ? year : _c, author = _b.author;
|
||||
var yearStr = year > year0 ? "".concat(year0, "-").concat(year) : year;
|
||||
return React.createElement("footer", null, author && React.createElement("div", null,
|
||||
"Copyright \u00A9 ",
|
||||
yearStr,
|
||||
" ",
|
||||
author,
|
||||
" All rights reserved."));
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
***************************************************************************** */
|
||||
|
||||
var __assign$1 = function() {
|
||||
__assign$1 = Object.assign || function __assign(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign$1.apply(this, arguments);
|
||||
};
|
||||
|
||||
function __rest$1(s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
***************************************************************************** */
|
||||
|
||||
var __assign = function() {
|
||||
__assign = Object.assign || function __assign(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
|
||||
function __rest(s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
function NavEntry(_a) {
|
||||
var _b = _a.entry, label = _b.label, link = _b.link, children = _b.children, dir = _a.dir, here = _a.here, childrenJSX = _a.children;
|
||||
var href = dir + link;
|
||||
var isHere = href.replace(/\/$/, '') === here; // remove trailing slash
|
||||
var isRHere = isHere || here.startsWith(href); // here or is children
|
||||
var _c = useState(isRHere), toggle = _c[0], setToggle = _c[1];
|
||||
var entryCls = 'nav-entry' + (isHere ? ' nav-here' : '');
|
||||
return (children === null || children === void 0 ? void 0 : children.length) ? React.createElement("div", { className: 'nav-dir' + (toggle ? ' nav-fold-open' : '') },
|
||||
React.createElement(React.Fragment, null,
|
||||
React.createElement("div", { className: entryCls },
|
||||
React.createElement(Link, { href: href }, label),
|
||||
React.createElement("svg", { viewBox: "0 0 8 8", onClick: function () { return setToggle(function (e) { return !e; }); } },
|
||||
React.createElement("polyline", { points: "6 3 4 5 2 3" }))),
|
||||
isHere ? childrenJSX : React.createElement(React.Fragment, null),
|
||||
React.createElement("div", { className: 'nav-dir-child' }, children.map(function (entry) { return React.createElement(NavEntry, { key: entry.link, entry: entry, dir: href, here: here }, childrenJSX); })))) : React.createElement("div", { className: entryCls },
|
||||
React.createElement(Link, { href: href }, label));
|
||||
}
|
||||
|
||||
function NavBase(_a) {
|
||||
var children = _a.children, headings = _a.headings, pathname = _a.pathname, entries = _a.entries, className = _a.className;
|
||||
var headingsJSX = React.createElement("ul", { className: "" }, headings.map(function (_a) {
|
||||
var label = _a.label, id = _a.id;
|
||||
return React.createElement("li", { key: id },
|
||||
React.createElement("a", { href: '#' + id }, label));
|
||||
}));
|
||||
return React.createElement("nav", { className: className },
|
||||
children,
|
||||
React.createElement("div", { className: "nav-root" },
|
||||
entries.map(function (entry) { return React.createElement(NavEntry, { key: entry.link, entry: entry, dir: '/', here: pathname }); }),
|
||||
headingsJSX));
|
||||
}
|
||||
|
||||
function NavHeader(_a) {
|
||||
var _b, _c, _d, _e, _f;
|
||||
var config = _a.config, onToggleFold = _a.onToggleFold;
|
||||
var title = config.title, subtitle = config.subtitle, icon0 = config.icon;
|
||||
var icon = typeof icon0 === 'string' ? { href: icon0 } : icon0;
|
||||
return React.createElement("header", null,
|
||||
React.createElement(Link, { href: "/", id: "icon-link" },
|
||||
(icon === null || icon === void 0 ? void 0 : icon.href) && React.createElement("img", { className: "icon", src: icon === null || icon === void 0 ? void 0 : icon.href, alt: (_b = icon === null || icon === void 0 ? void 0 : icon.alt) !== null && _b !== void 0 ? _b : 'icon', width: (_d = (_c = icon === null || icon === void 0 ? void 0 : icon.width) !== null && _c !== void 0 ? _c : icon === null || icon === void 0 ? void 0 : icon.size) !== null && _d !== void 0 ? _d : 96, height: (_f = (_e = icon === null || icon === void 0 ? void 0 : icon.height) !== null && _e !== void 0 ? _e : icon === null || icon === void 0 ? void 0 : icon.size) !== null && _f !== void 0 ? _f : 96 }),
|
||||
React.createElement("div", { className: "icon-text" },
|
||||
React.createElement("div", null, title),
|
||||
React.createElement("div", null, subtitle))),
|
||||
React.createElement("div", { className: "menu-toggle", onClick: onToggleFold }));
|
||||
}
|
||||
|
||||
function Nav(_a) {
|
||||
var config = _a.config, children = _a.children, props = __rest(_a, ["config", "children"]);
|
||||
var _b = useState(false), navFold = _b[0], setNavFold = _b[1];
|
||||
return (React.createElement(NavBase, __assign({ className: navFold ? 'open' : '', entries: config.nav }, props),
|
||||
React.createElement(NavHeader, { config: config.site, onToggleFold: function () { return setNavFold(function (e) { return !e; }); } }),
|
||||
children));
|
||||
}
|
||||
|
||||
function MetaInfo(_a) {
|
||||
var fields = _a.fields, data = _a.data;
|
||||
return React.createElement("div", null, fields.map(function (_a) {
|
||||
var label = _a.label, attr = _a.attr;
|
||||
var val = data[attr];
|
||||
return val == null ? null : React.createElement("div", { key: attr },
|
||||
React.createElement("span", null, label),
|
||||
React.createElement("span", null, val));
|
||||
}));
|
||||
}
|
||||
|
||||
function translate(data, _a) {
|
||||
var _b, _c;
|
||||
var locale = _a.locale, _d = _a.defaultLocale, defaultLocale = _d === void 0 ? '' : _d;
|
||||
if (data == null)
|
||||
return data;
|
||||
if (typeof data !== 'object')
|
||||
return data;
|
||||
if (data instanceof Array)
|
||||
return data;
|
||||
return (_c = (_b = (locale == null ? undefined : data[locale])) !== null && _b !== void 0 ? _b : data[defaultLocale]) !== null && _c !== void 0 ? _c : Object.values(data)[0];
|
||||
}
|
||||
|
||||
function translateNav(nav18, localeInfo) {
|
||||
return nav18.map(function (e) { return (__assign$1({ label: translate(e.label, localeInfo), link: e.link }, (e.children ? { children: translateNav(e.children, localeInfo) } : {}))); });
|
||||
}
|
||||
|
||||
function MDXPageBase(_a) {
|
||||
var _b, _c, _d;
|
||||
var children = _a.children, router = _a.router, _e = _a.meta, meta18 = _e === void 0 ? {} : _e, headings = _a.headings, config = _a.config;
|
||||
var meta = Object.fromEntries(Object.entries(meta18).map(function (_a) {
|
||||
var k = _a[0], v = _a[1];
|
||||
return [
|
||||
k, translate(v, router),
|
||||
];
|
||||
}));
|
||||
var title = meta.title, description = meta.description;
|
||||
var h1 = (_b = meta.h1) !== null && _b !== void 0 ? _b : title;
|
||||
var metaFields = (_d = (_c = config.metaFields) === null || _c === void 0 ? void 0 : _c.map(function (_a) {
|
||||
var label = _a.label, attr = _a.attr;
|
||||
return ({
|
||||
label: translate(label, router),
|
||||
attr: attr,
|
||||
});
|
||||
})) !== null && _d !== void 0 ? _d : [];
|
||||
var pathname = router.pathname;
|
||||
var navConfig = {
|
||||
site: __assign$1(__assign$1({}, config.site), { title: translate(config.site.title, router), subtitle: translate(config.site.subtitle, router) }),
|
||||
nav: translateNav(config.nav, router),
|
||||
};
|
||||
return React.createElement(React.Fragment, null,
|
||||
React.createElement(Head, null,
|
||||
title && React.createElement("title", null, title),
|
||||
description && React.createElement("meta", { name: "description", content: description })),
|
||||
React.createElement(Nav, { config: navConfig, pathname: pathname, headings: headings }),
|
||||
React.createElement("main", null,
|
||||
React.createElement("article", null,
|
||||
h1 ? React.createElement("h1", null, h1) : React.createElement(React.Fragment, null),
|
||||
React.createElement(MetaInfo, { fields: metaFields, data: meta }),
|
||||
children)),
|
||||
React.createElement(Footer, { config: config }));
|
||||
}
|
||||
var MDXPageFactory = function (config) {
|
||||
return function MDXPage(_a) {
|
||||
var children = _a.children, props = __rest$1(_a, ["children"]);
|
||||
return React.createElement(MDXPageBase, __assign$1({ config: config }, props), children);
|
||||
};
|
||||
};
|
||||
|
||||
export { Footer, MDXPageBase, MDXPageFactory, MetaInfo, translate, translateNav };
|
||||
//# sourceMappingURL=index.esm.js.map
|
1
dist/index.esm.js.map
vendored
Normal file
1
dist/index.esm.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
225
dist/index.js
vendored
Normal file
225
dist/index.js
vendored
Normal file
|
@ -0,0 +1,225 @@
|
|||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var Head = require('next/head');
|
||||
var Link = require('next/link');
|
||||
|
||||
function Footer(_a) {
|
||||
var config = _a.config;
|
||||
var year = new Date().getFullYear();
|
||||
var _b = config.site, _c = _b.startYear, year0 = _c === void 0 ? year : _c, author = _b.author;
|
||||
var yearStr = year > year0 ? "".concat(year0, "-").concat(year) : year;
|
||||
return React.createElement("footer", null, author && React.createElement("div", null,
|
||||
"Copyright \u00A9 ",
|
||||
yearStr,
|
||||
" ",
|
||||
author,
|
||||
" All rights reserved."));
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
***************************************************************************** */
|
||||
|
||||
var __assign$1 = function() {
|
||||
__assign$1 = Object.assign || function __assign(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign$1.apply(this, arguments);
|
||||
};
|
||||
|
||||
function __rest$1(s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
***************************************************************************** */
|
||||
|
||||
var __assign = function() {
|
||||
__assign = Object.assign || function __assign(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
|
||||
function __rest(s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
function NavEntry(_a) {
|
||||
var _b = _a.entry, label = _b.label, link = _b.link, children = _b.children, dir = _a.dir, here = _a.here, childrenJSX = _a.children;
|
||||
var href = dir + link;
|
||||
var isHere = href.replace(/\/$/, '') === here; // remove trailing slash
|
||||
var isRHere = isHere || here.startsWith(href); // here or is children
|
||||
var _c = React.useState(isRHere), toggle = _c[0], setToggle = _c[1];
|
||||
var entryCls = 'nav-entry' + (isHere ? ' nav-here' : '');
|
||||
return (children === null || children === void 0 ? void 0 : children.length) ? React.createElement("div", { className: 'nav-dir' + (toggle ? ' nav-fold-open' : '') },
|
||||
React.createElement(React.Fragment, null,
|
||||
React.createElement("div", { className: entryCls },
|
||||
React.createElement(Link, { href: href }, label),
|
||||
React.createElement("svg", { viewBox: "0 0 8 8", onClick: function () { return setToggle(function (e) { return !e; }); } },
|
||||
React.createElement("polyline", { points: "6 3 4 5 2 3" }))),
|
||||
isHere ? childrenJSX : React.createElement(React.Fragment, null),
|
||||
React.createElement("div", { className: 'nav-dir-child' }, children.map(function (entry) { return React.createElement(NavEntry, { key: entry.link, entry: entry, dir: href, here: here }, childrenJSX); })))) : React.createElement("div", { className: entryCls },
|
||||
React.createElement(Link, { href: href }, label));
|
||||
}
|
||||
|
||||
function NavBase(_a) {
|
||||
var children = _a.children, headings = _a.headings, pathname = _a.pathname, entries = _a.entries, className = _a.className;
|
||||
var headingsJSX = React.createElement("ul", { className: "" }, headings.map(function (_a) {
|
||||
var label = _a.label, id = _a.id;
|
||||
return React.createElement("li", { key: id },
|
||||
React.createElement("a", { href: '#' + id }, label));
|
||||
}));
|
||||
return React.createElement("nav", { className: className },
|
||||
children,
|
||||
React.createElement("div", { className: "nav-root" },
|
||||
entries.map(function (entry) { return React.createElement(NavEntry, { key: entry.link, entry: entry, dir: '/', here: pathname }); }),
|
||||
headingsJSX));
|
||||
}
|
||||
|
||||
function NavHeader(_a) {
|
||||
var _b, _c, _d, _e, _f;
|
||||
var config = _a.config, onToggleFold = _a.onToggleFold;
|
||||
var title = config.title, subtitle = config.subtitle, icon0 = config.icon;
|
||||
var icon = typeof icon0 === 'string' ? { href: icon0 } : icon0;
|
||||
return React.createElement("header", null,
|
||||
React.createElement(Link, { href: "/", id: "icon-link" },
|
||||
(icon === null || icon === void 0 ? void 0 : icon.href) && React.createElement("img", { className: "icon", src: icon === null || icon === void 0 ? void 0 : icon.href, alt: (_b = icon === null || icon === void 0 ? void 0 : icon.alt) !== null && _b !== void 0 ? _b : 'icon', width: (_d = (_c = icon === null || icon === void 0 ? void 0 : icon.width) !== null && _c !== void 0 ? _c : icon === null || icon === void 0 ? void 0 : icon.size) !== null && _d !== void 0 ? _d : 96, height: (_f = (_e = icon === null || icon === void 0 ? void 0 : icon.height) !== null && _e !== void 0 ? _e : icon === null || icon === void 0 ? void 0 : icon.size) !== null && _f !== void 0 ? _f : 96 }),
|
||||
React.createElement("div", { className: "icon-text" },
|
||||
React.createElement("div", null, title),
|
||||
React.createElement("div", null, subtitle))),
|
||||
React.createElement("div", { className: "menu-toggle", onClick: onToggleFold }));
|
||||
}
|
||||
|
||||
function Nav(_a) {
|
||||
var config = _a.config, children = _a.children, props = __rest(_a, ["config", "children"]);
|
||||
var _b = React.useState(false), navFold = _b[0], setNavFold = _b[1];
|
||||
return (React.createElement(NavBase, __assign({ className: navFold ? 'open' : '', entries: config.nav }, props),
|
||||
React.createElement(NavHeader, { config: config.site, onToggleFold: function () { return setNavFold(function (e) { return !e; }); } }),
|
||||
children));
|
||||
}
|
||||
|
||||
function MetaInfo(_a) {
|
||||
var fields = _a.fields, data = _a.data;
|
||||
return React.createElement("div", null, fields.map(function (_a) {
|
||||
var label = _a.label, attr = _a.attr;
|
||||
var val = data[attr];
|
||||
return val == null ? null : React.createElement("div", { key: attr },
|
||||
React.createElement("span", null, label),
|
||||
React.createElement("span", null, val));
|
||||
}));
|
||||
}
|
||||
|
||||
function translate(data, _a) {
|
||||
var _b, _c;
|
||||
var locale = _a.locale, _d = _a.defaultLocale, defaultLocale = _d === void 0 ? '' : _d;
|
||||
if (data == null)
|
||||
return data;
|
||||
if (typeof data !== 'object')
|
||||
return data;
|
||||
if (data instanceof Array)
|
||||
return data;
|
||||
return (_c = (_b = (locale == null ? undefined : data[locale])) !== null && _b !== void 0 ? _b : data[defaultLocale]) !== null && _c !== void 0 ? _c : Object.values(data)[0];
|
||||
}
|
||||
|
||||
function translateNav(nav18, localeInfo) {
|
||||
return nav18.map(function (e) { return (__assign$1({ label: translate(e.label, localeInfo), link: e.link }, (e.children ? { children: translateNav(e.children, localeInfo) } : {}))); });
|
||||
}
|
||||
|
||||
function MDXPageBase(_a) {
|
||||
var _b, _c, _d;
|
||||
var children = _a.children, router = _a.router, _e = _a.meta, meta18 = _e === void 0 ? {} : _e, headings = _a.headings, config = _a.config;
|
||||
var meta = Object.fromEntries(Object.entries(meta18).map(function (_a) {
|
||||
var k = _a[0], v = _a[1];
|
||||
return [
|
||||
k, translate(v, router),
|
||||
];
|
||||
}));
|
||||
var title = meta.title, description = meta.description;
|
||||
var h1 = (_b = meta.h1) !== null && _b !== void 0 ? _b : title;
|
||||
var metaFields = (_d = (_c = config.metaFields) === null || _c === void 0 ? void 0 : _c.map(function (_a) {
|
||||
var label = _a.label, attr = _a.attr;
|
||||
return ({
|
||||
label: translate(label, router),
|
||||
attr: attr,
|
||||
});
|
||||
})) !== null && _d !== void 0 ? _d : [];
|
||||
var pathname = router.pathname;
|
||||
var navConfig = {
|
||||
site: __assign$1(__assign$1({}, config.site), { title: translate(config.site.title, router), subtitle: translate(config.site.subtitle, router) }),
|
||||
nav: translateNav(config.nav, router),
|
||||
};
|
||||
return React.createElement(React.Fragment, null,
|
||||
React.createElement(Head, null,
|
||||
title && React.createElement("title", null, title),
|
||||
description && React.createElement("meta", { name: "description", content: description })),
|
||||
React.createElement(Nav, { config: navConfig, pathname: pathname, headings: headings }),
|
||||
React.createElement("main", null,
|
||||
React.createElement("article", null,
|
||||
h1 ? React.createElement("h1", null, h1) : React.createElement(React.Fragment, null),
|
||||
React.createElement(MetaInfo, { fields: metaFields, data: meta }),
|
||||
children)),
|
||||
React.createElement(Footer, { config: config }));
|
||||
}
|
||||
var MDXPageFactory = function (config) {
|
||||
return function MDXPage(_a) {
|
||||
var children = _a.children, props = __rest$1(_a, ["children"]);
|
||||
return React.createElement(MDXPageBase, __assign$1({ config: config }, props), children);
|
||||
};
|
||||
};
|
||||
|
||||
exports.Footer = Footer;
|
||||
exports.MDXPageBase = MDXPageBase;
|
||||
exports.MDXPageFactory = MDXPageFactory;
|
||||
exports.MetaInfo = MetaInfo;
|
||||
exports.translate = translate;
|
||||
exports.translateNav = translateNav;
|
||||
//# sourceMappingURL=index.js.map
|
1
dist/index.js.map
vendored
Normal file
1
dist/index.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
52
package.json
Normal file
52
package.json
Normal file
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"name": "@sup39/mdx-page",
|
||||
"version": "0.1.0",
|
||||
"author": "sup39 <dev@sup39.dev>",
|
||||
"repository": "github.com:sup39/supMDX-page",
|
||||
"description": "Page component for supMDX",
|
||||
"license": "MIT",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.esm.js",
|
||||
"files": [
|
||||
"dist/*"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "rollup -c",
|
||||
"lint": "eslint --ext .ts --ext .tsx src/",
|
||||
"pre-commit:add": "git add -u"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"env": {
|
||||
"es6": true
|
||||
},
|
||||
"extends": [
|
||||
"@sup39/typescript"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.12",
|
||||
"@babel/preset-env": "^7.20.2",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@rollup/plugin-babel": "^6.0.3",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
"@rollup/plugin-typescript": "^11.0.0",
|
||||
"@sup39/eslint-config-typescript": "^0.1.5",
|
||||
"@types/react": "^18.0.28",
|
||||
"eslint": "^8.34.0",
|
||||
"pre-commit": "^1.2.2",
|
||||
"rollup": "^3.15.0",
|
||||
"typescript": "^4.9.5"
|
||||
},
|
||||
"pre-commit": [
|
||||
"lint",
|
||||
"build",
|
||||
"pre-commit:add"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"next": "^13",
|
||||
"react": "^18"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sup39/mdx-nav": "../supMDX-nav"
|
||||
}
|
||||
}
|
32
rollup.config.mjs
Normal file
32
rollup.config.mjs
Normal file
|
@ -0,0 +1,32 @@
|
|||
import typescript from '@rollup/plugin-typescript';
|
||||
import babel from '@rollup/plugin-babel';
|
||||
import resolve from '@rollup/plugin-node-resolve';
|
||||
|
||||
export default {
|
||||
input: 'src/index.tsx',
|
||||
output: [
|
||||
{
|
||||
file: 'dist/index.js',
|
||||
format: 'cjs',
|
||||
sourcemap: true,
|
||||
},
|
||||
{
|
||||
file: 'dist/index.esm.js',
|
||||
format: 'esm',
|
||||
sourcemap: true,
|
||||
},
|
||||
],
|
||||
plugins: [
|
||||
resolve(),
|
||||
typescript(),
|
||||
babel({
|
||||
babelHelpers: 'bundled',
|
||||
presets: [
|
||||
['@babel/preset-env', {targets: {node: 'current'}}],
|
||||
'@babel/preset-react',
|
||||
],
|
||||
exclude: 'node_modules/**',
|
||||
}),
|
||||
],
|
||||
external: ['react', 'react-dom', 'next/link', 'next/head'],
|
||||
};
|
16
src/Footer.tsx
Normal file
16
src/Footer.tsx
Normal file
|
@ -0,0 +1,16 @@
|
|||
import React from 'react';
|
||||
export type FooterConfig = {
|
||||
site: {
|
||||
startYear?: number
|
||||
author: string
|
||||
}
|
||||
};
|
||||
|
||||
export function Footer({config}: {config: FooterConfig}) {
|
||||
const year = new Date().getFullYear();
|
||||
const {site: {startYear: year0 = year, author}} = config;
|
||||
const yearStr = year>year0 ? `${year0}-${year}` : year;
|
||||
return <footer>{
|
||||
author && <div>Copyright © {yearStr} {author} All rights reserved.</div>
|
||||
}</footer>;
|
||||
}
|
83
src/MDXPage.tsx
Normal file
83
src/MDXPage.tsx
Normal file
|
@ -0,0 +1,83 @@
|
|||
import React from 'react';
|
||||
import Head from 'next/head';
|
||||
import {Nav, NavHeaderConfig} from '@sup39/mdx-nav';
|
||||
import {Footer} from './Footer';
|
||||
import {MetaInfo} from './MetaInfo';
|
||||
import {I18N, LocaleInfo, translate} from './i18n';
|
||||
import {I18NNavEntryInfo, translateNav} from './i18n-nav';
|
||||
|
||||
type HeadingInfo = {
|
||||
tagName: string;
|
||||
label: string;
|
||||
id: string;
|
||||
};
|
||||
|
||||
export type MDXProps = {
|
||||
children: JSX.Element
|
||||
router: {pathname: string} & LocaleInfo
|
||||
meta: Partial<{
|
||||
title: I18N<string>
|
||||
description: I18N<string>
|
||||
h1: I18N<string>
|
||||
[key: string]: any
|
||||
}>
|
||||
headings: HeadingInfo[]
|
||||
config: MDXConfig
|
||||
};
|
||||
|
||||
export type MDXConfig = {
|
||||
site: {
|
||||
startYear?: number
|
||||
author: string
|
||||
title: I18N<string>
|
||||
subtitle?: I18N<string>
|
||||
} & Omit<NavHeaderConfig, 'title'|'subtitle'>
|
||||
metaFields?: {label: I18N<string>, attr: string}[]
|
||||
nav: I18NNavEntryInfo[]
|
||||
}
|
||||
|
||||
export function MDXPageBase({
|
||||
children, router, meta: meta18={}, headings, config,
|
||||
}: MDXProps) {
|
||||
const meta = Object.fromEntries(Object.entries(meta18).map(([k, v]) => [
|
||||
k, translate(v, router),
|
||||
]));
|
||||
const {title, description} = meta;
|
||||
const h1 = meta.h1 ?? title;
|
||||
|
||||
const metaFields = config.metaFields?.map(({label, attr}) => ({
|
||||
label: translate(label, router),
|
||||
attr,
|
||||
})) ?? [];
|
||||
|
||||
const {pathname} = router;
|
||||
const navConfig = {
|
||||
site: {
|
||||
...config.site,
|
||||
title: translate(config.site.title, router),
|
||||
subtitle: translate(config.site.subtitle, router),
|
||||
},
|
||||
nav: translateNav(config.nav, router),
|
||||
};
|
||||
|
||||
return <>
|
||||
<Head>
|
||||
{title && <title>{title}</title>}
|
||||
{description && <meta name="description" content={description} />}
|
||||
</Head>
|
||||
<Nav config={navConfig} pathname={pathname} headings={headings} />
|
||||
<main>
|
||||
<article>
|
||||
{h1 ? <h1>{h1}</h1> : <></>}
|
||||
<MetaInfo fields={metaFields} data={meta} />
|
||||
{children}
|
||||
</article>
|
||||
</main>
|
||||
<Footer config={config} />
|
||||
</>;
|
||||
}
|
||||
|
||||
export const MDXPageFactory = (config: MDXConfig) =>
|
||||
function MDXPage({children, ...props}: Omit<MDXProps, 'config'>) {
|
||||
return <MDXPageBase config={config} {...props}>{children}</MDXPageBase>;
|
||||
};
|
19
src/MetaInfo.tsx
Normal file
19
src/MetaInfo.tsx
Normal file
|
@ -0,0 +1,19 @@
|
|||
import React from 'react';
|
||||
|
||||
export type MetaInfoProps = {
|
||||
data: Record<string, any>
|
||||
fields: {
|
||||
label: string
|
||||
attr: string
|
||||
}[]
|
||||
};
|
||||
|
||||
export function MetaInfo({fields, data}: MetaInfoProps) {
|
||||
return <div>{fields.map(({label, attr}) => {
|
||||
const val = data[attr];
|
||||
return val == null ? null : <div key={attr}>
|
||||
<span>{label}</span>
|
||||
<span>{val}</span>
|
||||
</div>;
|
||||
})}</div>;
|
||||
}
|
19
src/i18n-nav.ts
Normal file
19
src/i18n-nav.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
import type {NavEntryInfo} from '@sup39/mdx-nav';
|
||||
import {I18N, translate} from './i18n';
|
||||
|
||||
export type I18NNavEntryInfo = {
|
||||
label: I18N<string>
|
||||
link: string
|
||||
children?: I18NNavEntryInfo[]
|
||||
};
|
||||
|
||||
export function translateNav(
|
||||
nav18: I18NNavEntryInfo[],
|
||||
localeInfo: Parameters<typeof translate>[1],
|
||||
): NavEntryInfo[] {
|
||||
return nav18.map(e => ({
|
||||
label: translate(e.label, localeInfo),
|
||||
link: e.link,
|
||||
...(e.children ? {children: translateNav(e.children, localeInfo)} : {}),
|
||||
}));
|
||||
}
|
29
src/i18n.ts
Normal file
29
src/i18n.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
export type NonRecordType = boolean|number|bigint|string|symbol|any[];
|
||||
export type I18N<T> = (T & NonRecordType) | Record<string, T>;
|
||||
export type LocaleInfo = {
|
||||
locale?: string
|
||||
defaultLocale?: string
|
||||
};
|
||||
|
||||
export function translate<T>(
|
||||
data: I18N<T>,
|
||||
{locale, defaultLocale=''}: LocaleInfo,
|
||||
): T;
|
||||
export function translate<T>(
|
||||
data: I18N<T>|null,
|
||||
{locale, defaultLocale=''}: LocaleInfo,
|
||||
): null;
|
||||
export function translate<T>(
|
||||
data: I18N<T>|undefined,
|
||||
{locale, defaultLocale=''}: LocaleInfo,
|
||||
): undefined;
|
||||
export function translate<T, U extends null|undefined>(
|
||||
data: I18N<T>|U,
|
||||
{locale, defaultLocale=''}: LocaleInfo,
|
||||
): T|U {
|
||||
if (data == null) return data;
|
||||
if (typeof data !== 'object') return data;
|
||||
if (data instanceof Array) return data;
|
||||
return (locale == null ? undefined : data[locale]) ??
|
||||
data[defaultLocale] ?? Object.values(data)[0];
|
||||
}
|
5
src/index.tsx
Normal file
5
src/index.tsx
Normal file
|
@ -0,0 +1,5 @@
|
|||
export * from './Footer';
|
||||
export * from './MDXPage';
|
||||
export * from './MetaInfo';
|
||||
export * from './i18n';
|
||||
export * from './i18n-nav';
|
26
tsconfig.json
Normal file
26
tsconfig.json
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "es6",
|
||||
"outDir": "dist",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"declaration": true,
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"sourceMap": true,
|
||||
"jsx": "react"
|
||||
},
|
||||
"include": [
|
||||
"src/*.ts",
|
||||
"src/*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
Loading…
Reference in a new issue