wiki-formant 0.13.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -25
- package/bin/check-classes.mjs +2 -3
- package/dist/analytics.d.ts +0 -1
- package/dist/analytics.js +0 -1
- package/dist/block-views.d.ts +97 -0
- package/dist/block-views.js +119 -0
- package/dist/blocks.d.ts +0 -1
- package/dist/blocks.js +1 -2
- package/dist/combobox.d.ts +0 -1
- package/dist/combobox.js +0 -1
- package/dist/conformance.d.ts +0 -3
- package/dist/conformance.js +40 -38
- package/dist/crawlers.d.ts +0 -1
- package/dist/crawlers.js +0 -1
- package/dist/dom.d.ts +0 -1
- package/dist/dom.js +0 -1
- package/dist/editor.d.ts +101 -0
- package/dist/editor.js +218 -0
- package/dist/feed.d.ts +0 -1
- package/dist/feed.js +0 -1
- package/dist/freshness.d.ts +0 -1
- package/dist/freshness.js +2 -2
- package/dist/headings.d.ts +0 -1
- package/dist/headings.js +1 -3
- package/dist/html.d.ts +16 -0
- package/dist/html.js +23 -0
- package/dist/http.d.ts +20 -1
- package/dist/http.js +23 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/license.d.ts +0 -1
- package/dist/license.js +0 -1
- package/dist/link-check.d.ts +92 -0
- package/dist/link-check.js +249 -0
- package/dist/links.d.ts +0 -1
- package/dist/links.js +1 -6
- package/dist/maps.d.ts +0 -1
- package/dist/maps.js +2 -2
- package/dist/markdown.d.ts +1 -1
- package/dist/markdown.js +34 -3
- package/dist/mcp.d.ts +17 -7
- package/dist/mcp.js +8 -8
- package/dist/pagination.d.ts +19 -1
- package/dist/pagination.js +21 -1
- package/dist/rate-limit.d.ts +18 -1
- package/dist/rate-limit.js +22 -1
- package/dist/react-server.d.ts +91 -9
- package/dist/react-server.js +68 -16
- package/dist/react.d.ts +37 -48
- package/dist/react.js +44 -23
- package/dist/revisions.d.ts +0 -1
- package/dist/revisions.js +0 -1
- package/dist/rola.d.ts +0 -1
- package/dist/rola.js +0 -1
- package/dist/seeded.d.ts +11 -0
- package/dist/seeded.js +32 -0
- package/dist/sidebar.d.ts +0 -1
- package/dist/sidebar.js +0 -1
- package/dist/taxonomy.d.ts +0 -1
- package/dist/taxonomy.js +0 -1
- package/dist/text.d.ts +14 -1
- package/dist/text.js +15 -2
- package/dist/tiptap.d.ts +1 -1
- package/dist/tiptap.js +1 -2
- package/dist/validation.d.ts +2 -3
- package/dist/validation.js +4 -5
- package/dist/versioning.d.ts +0 -1
- package/dist/versioning.js +0 -1
- package/dist/well-known.d.ts +19 -2
- package/dist/well-known.js +28 -2
- package/dist/x402.d.ts +2 -11
- package/dist/x402.js +4 -16
- package/package.json +52 -27
- package/dist/analytics.d.ts.map +0 -1
- package/dist/analytics.js.map +0 -1
- package/dist/blocks.d.ts.map +0 -1
- package/dist/blocks.js.map +0 -1
- package/dist/combobox.d.ts.map +0 -1
- package/dist/combobox.js.map +0 -1
- package/dist/conformance.d.ts.map +0 -1
- package/dist/conformance.js.map +0 -1
- package/dist/crawlers.d.ts.map +0 -1
- package/dist/crawlers.js.map +0 -1
- package/dist/dom.d.ts.map +0 -1
- package/dist/dom.js.map +0 -1
- package/dist/entities.d.ts +0 -3
- package/dist/entities.d.ts.map +0 -1
- package/dist/entities.js +0 -30
- package/dist/entities.js.map +0 -1
- package/dist/feed.d.ts.map +0 -1
- package/dist/feed.js.map +0 -1
- package/dist/freshness.d.ts.map +0 -1
- package/dist/freshness.js.map +0 -1
- package/dist/headings.d.ts.map +0 -1
- package/dist/headings.js.map +0 -1
- package/dist/http.d.ts.map +0 -1
- package/dist/http.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/license.d.ts.map +0 -1
- package/dist/license.js.map +0 -1
- package/dist/links.d.ts.map +0 -1
- package/dist/links.js.map +0 -1
- package/dist/maps.d.ts.map +0 -1
- package/dist/maps.js.map +0 -1
- package/dist/markdown.d.ts.map +0 -1
- package/dist/markdown.js.map +0 -1
- package/dist/mcp.d.ts.map +0 -1
- package/dist/mcp.js.map +0 -1
- package/dist/pagination.d.ts.map +0 -1
- package/dist/pagination.js.map +0 -1
- package/dist/rate-limit.d.ts.map +0 -1
- package/dist/rate-limit.js.map +0 -1
- package/dist/react-server.d.ts.map +0 -1
- package/dist/react-server.js.map +0 -1
- package/dist/react.d.ts.map +0 -1
- package/dist/react.js.map +0 -1
- package/dist/revisions.d.ts.map +0 -1
- package/dist/revisions.js.map +0 -1
- package/dist/rola.d.ts.map +0 -1
- package/dist/rola.js.map +0 -1
- package/dist/sidebar.d.ts.map +0 -1
- package/dist/sidebar.js.map +0 -1
- package/dist/taxonomy.d.ts.map +0 -1
- package/dist/taxonomy.js.map +0 -1
- package/dist/text.d.ts.map +0 -1
- package/dist/text.js.map +0 -1
- package/dist/tiptap.d.ts.map +0 -1
- package/dist/tiptap.js.map +0 -1
- package/dist/validation.d.ts.map +0 -1
- package/dist/validation.js.map +0 -1
- package/dist/versioning.d.ts.map +0 -1
- package/dist/versioning.js.map +0 -1
- package/dist/well-known.d.ts.map +0 -1
- package/dist/well-known.js.map +0 -1
- package/dist/x402.d.ts.map +0 -1
- package/dist/x402.js.map +0 -1
package/dist/react-server.d.ts
CHANGED
|
@@ -13,9 +13,18 @@ export interface WikiLinkProps {
|
|
|
13
13
|
className?: string;
|
|
14
14
|
title?: string;
|
|
15
15
|
'aria-current'?: 'true' | 'page' | undefined;
|
|
16
|
+
/** `prev`/`next` on the foot nav — the half that makes the pair machine-readable. */
|
|
17
|
+
rel?: string;
|
|
16
18
|
children?: ReactNode;
|
|
17
19
|
}
|
|
18
20
|
export type WikiLinkComponent = ComponentType<WikiLinkProps>;
|
|
21
|
+
/**
|
|
22
|
+
* The default for anything that does not need client-side navigation.
|
|
23
|
+
*
|
|
24
|
+
* Exported because `block-views` renders links too and had declared the same
|
|
25
|
+
* three lines; a default that exists twice is a default that can diverge.
|
|
26
|
+
*/
|
|
27
|
+
export declare const Anchor: WikiLinkComponent;
|
|
19
28
|
/**
|
|
20
29
|
* Class names differ per wiki and always will — unlike the rail's `wiki-rail__*`
|
|
21
30
|
* tree, which is a shared convention, these are each design system's own words
|
|
@@ -50,29 +59,102 @@ export interface FacetBarProps {
|
|
|
50
59
|
export declare function FacetBar({ link: Link, facets, letters, alphaLabel, classNames, }: FacetBarProps): import("react").JSX.Element | null;
|
|
51
60
|
export interface BreadcrumbItem {
|
|
52
61
|
label: string;
|
|
53
|
-
|
|
62
|
+
/**
|
|
63
|
+
* Omit to render the crumb as plain text rather than a link — a section that
|
|
64
|
+
* groups pages but has no page of its own. A crumb with no href is left out
|
|
65
|
+
* of the `BreadcrumbList` too, since a `ListItem` with no `item` is invalid.
|
|
66
|
+
*/
|
|
67
|
+
href?: string;
|
|
54
68
|
}
|
|
55
69
|
export interface BreadcrumbsProps {
|
|
56
70
|
items: BreadcrumbItem[];
|
|
57
71
|
/**
|
|
58
72
|
* Origin the JSON-LD `item` URLs are resolved against, without a trailing
|
|
59
73
|
* slash. Structured-data URLs must be absolute — Google rejects relative
|
|
60
|
-
* paths — and this package cannot know the site it is rendering for.
|
|
74
|
+
* paths — and this package cannot know the site it is rendering for. Omit it
|
|
75
|
+
* to render the trail with no structured data at all.
|
|
61
76
|
*/
|
|
62
|
-
base
|
|
77
|
+
base?: string;
|
|
63
78
|
className?: string;
|
|
64
79
|
/** Defaults to a plain `<a>`, which is what a crumb trail wants. */
|
|
65
80
|
link?: WikiLinkComponent;
|
|
81
|
+
/**
|
|
82
|
+
* What the final crumb renders as.
|
|
83
|
+
*
|
|
84
|
+
* `h1` is not decoration: on a wiki whose page title IS the last crumb, the
|
|
85
|
+
* trail and the heading are the same words, and rendering both means either
|
|
86
|
+
* saying it twice or shipping a page with no h1 at all. The `breadcrumb-h1`
|
|
87
|
+
* class carries the size difference.
|
|
88
|
+
*/
|
|
89
|
+
lastAs?: 'span' | 'h1';
|
|
90
|
+
/**
|
|
91
|
+
* Fewest crumbs worth rendering. Default 2 — one crumb is not a trail.
|
|
92
|
+
*
|
|
93
|
+
* A wiki whose last crumb doubles as the page heading passes 1, because there
|
|
94
|
+
* the single crumb is not a trail either, it is the title.
|
|
95
|
+
*/
|
|
96
|
+
minItems?: number;
|
|
66
97
|
}
|
|
67
98
|
/**
|
|
68
99
|
* The trail, plus the `BreadcrumbList` that makes it a rich result.
|
|
69
100
|
*
|
|
70
|
-
*
|
|
101
|
+
* THE TWO ARE EMITTED TOGETHER ON PURPOSE. A trail whose JSON-LD is written
|
|
71
102
|
* somewhere else is a trail that will one day disagree with its own markup, and
|
|
72
|
-
* Google penalises exactly that.
|
|
103
|
+
* Google penalises exactly that. Both wikis had proved the point before
|
|
104
|
+
* adopting this: each rendered its crumbs in a component and built its
|
|
105
|
+
* `BreadcrumbList` in a different file — a page module in one, a `*-ld.ts` in
|
|
106
|
+
* the other — and one of them carried a comment noting the risk it was taking.
|
|
107
|
+
*
|
|
108
|
+
* Markup is a `<nav>` wrapping an `<ol>`: a breadcrumb trail is an ordered list
|
|
109
|
+
* and assistive technology announces it as one. The separators are list items
|
|
110
|
+
* marked `aria-hidden`, so they are not read out as content.
|
|
111
|
+
*/
|
|
112
|
+
export declare function Breadcrumbs({ items, base, className, link: Link, lastAs, minItems, }: BreadcrumbsProps): import("react").JSX.Element | null;
|
|
113
|
+
/**
|
|
114
|
+
* The standard page-top row: the trail, plus optional right-aligned actions.
|
|
115
|
+
*
|
|
116
|
+
* The column it sits in is the one its route declares — the row reads the
|
|
117
|
+
* page's own max-width by inheritance, so a trail can no longer disagree with
|
|
118
|
+
* the content it titles.
|
|
119
|
+
*/
|
|
120
|
+
export declare function BreadcrumbsRow({ actions, className, ...props }: BreadcrumbsProps & {
|
|
121
|
+
actions?: ReactNode;
|
|
122
|
+
}): import("react").JSX.Element;
|
|
123
|
+
/** One end of the foot nav: where it goes and what it is called. */
|
|
124
|
+
export interface PageNavRef {
|
|
125
|
+
title: string;
|
|
126
|
+
href: string;
|
|
127
|
+
}
|
|
128
|
+
export interface PageNavProps {
|
|
129
|
+
prev?: PageNavRef | null;
|
|
130
|
+
next?: PageNavRef | null;
|
|
131
|
+
link?: WikiLinkComponent;
|
|
132
|
+
/** The landmark's accessible name. */
|
|
133
|
+
label?: string;
|
|
134
|
+
prevLabel?: string;
|
|
135
|
+
nextLabel?: string;
|
|
136
|
+
/**
|
|
137
|
+
* The arrows. `ReactNode` rather than a string because both wikis draw them
|
|
138
|
+
* with an icon component, and this package is not acquiring an icon peer to
|
|
139
|
+
* hold two glyphs.
|
|
140
|
+
*/
|
|
141
|
+
prevGlyph?: ReactNode;
|
|
142
|
+
nextGlyph?: ReactNode;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* The sequential read at the foot of an article — the move the infobox rail's
|
|
146
|
+
* lateral links do not cover.
|
|
147
|
+
*
|
|
148
|
+
* Ordering is entirely the caller's; pair this with `adjacentPages` from
|
|
149
|
+
* `wiki-formant/pagination` over a list you already hold. Both wikis had this
|
|
150
|
+
* markup and had already drifted on the parts that matter rather than the parts
|
|
151
|
+
* that show: one carried `rel="prev"`/`rel="next"` and an `aria-label` and the
|
|
152
|
+
* other carried neither, and the one without expressed its right-hand alignment
|
|
153
|
+
* as two inline utilities instead of the modifier its own stylesheet defines.
|
|
73
154
|
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
155
|
+
* The `page-nav__*` class names are NOT props, for the reason `WikiRail`'s are
|
|
156
|
+
* not: they are the convention both stylesheets already implement, and making
|
|
157
|
+
* them configurable is how a convention forks. The empty `<div>` holds the
|
|
158
|
+
* first article's left column so the next link stays in the right one.
|
|
76
159
|
*/
|
|
77
|
-
export declare function
|
|
78
|
-
//# sourceMappingURL=react-server.d.ts.map
|
|
160
|
+
export declare function PageNav({ prev, next, link: Link, label, prevLabel, nextLabel, prevGlyph, nextGlyph, }: PageNavProps): import("react").JSX.Element | null;
|
package/dist/react-server.js
CHANGED
|
@@ -19,8 +19,13 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
19
19
|
// back to a full page load on every press. React is an optional peer, as it is
|
|
20
20
|
// for `wiki-formant/react`.
|
|
21
21
|
import { Fragment } from 'react';
|
|
22
|
-
/**
|
|
23
|
-
|
|
22
|
+
/**
|
|
23
|
+
* The default for anything that does not need client-side navigation.
|
|
24
|
+
*
|
|
25
|
+
* Exported because `block-views` renders links too and had declared the same
|
|
26
|
+
* three lines; a default that exists twice is a default that can diverge.
|
|
27
|
+
*/
|
|
28
|
+
export const Anchor = ({ href, className, children }) => _jsx("a", { href: href, className: className, children: children });
|
|
24
29
|
/**
|
|
25
30
|
* The section's second axis, as pressable chips.
|
|
26
31
|
*
|
|
@@ -40,23 +45,70 @@ export function FacetBar({ link: Link, facets, letters, alphaLabel = 'A–Z', cl
|
|
|
40
45
|
/**
|
|
41
46
|
* The trail, plus the `BreadcrumbList` that makes it a rich result.
|
|
42
47
|
*
|
|
43
|
-
*
|
|
48
|
+
* THE TWO ARE EMITTED TOGETHER ON PURPOSE. A trail whose JSON-LD is written
|
|
44
49
|
* somewhere else is a trail that will one day disagree with its own markup, and
|
|
45
|
-
* Google penalises exactly that.
|
|
50
|
+
* Google penalises exactly that. Both wikis had proved the point before
|
|
51
|
+
* adopting this: each rendered its crumbs in a component and built its
|
|
52
|
+
* `BreadcrumbList` in a different file — a page module in one, a `*-ld.ts` in
|
|
53
|
+
* the other — and one of them carried a comment noting the risk it was taking.
|
|
46
54
|
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
55
|
+
* Markup is a `<nav>` wrapping an `<ol>`: a breadcrumb trail is an ordered list
|
|
56
|
+
* and assistive technology announces it as one. The separators are list items
|
|
57
|
+
* marked `aria-hidden`, so they are not read out as content.
|
|
49
58
|
*/
|
|
50
|
-
export function Breadcrumbs({ items, base, className = '', link: Link = Anchor }) {
|
|
51
|
-
if (!items || items.length
|
|
59
|
+
export function Breadcrumbs({ items, base, className = '', link: Link = Anchor, lastAs = 'span', minItems = 2, }) {
|
|
60
|
+
if (!items || items.length < minItems)
|
|
52
61
|
return null;
|
|
53
62
|
const absolute = (path) => /^https?:\/\//.test(path) ? path : `${base}${path.startsWith('/') ? path : `/${path}`}`;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
63
|
+
// A one-item list is noise in the index even where the trail is worth
|
|
64
|
+
// rendering. Every crumb is listed, but only a crumb with an href carries an
|
|
65
|
+
// `item`: schema.org's documented shape for the page you are already on is a
|
|
66
|
+
// final `ListItem` with a name and no URL, so dropping it would lose the leaf
|
|
67
|
+
// the trail exists to name.
|
|
68
|
+
const structured = base && items.length > 1;
|
|
69
|
+
return (_jsxs(_Fragment, { children: [_jsx("nav", { "aria-label": "Breadcrumb", className: `breadcrumbs ${className}`.trim(), children: _jsx("ol", { children: items.map((item, i) => {
|
|
70
|
+
const isLast = i === items.length - 1;
|
|
71
|
+
const Last = lastAs === 'h1' ? 'h1' : 'span';
|
|
72
|
+
return (_jsxs(Fragment, { children: [i > 0 && _jsx("li", { className: "separator", "aria-hidden": "true", children: "/" }), _jsx("li", { children: isLast ? (_jsx(Last, { className: lastAs === 'h1' ? 'breadcrumb-h1' : 'breadcrumb-current', "aria-current": "page", children: item.label })) : item.href ? (_jsx(Link, { href: item.href, className: "breadcrumb-link", title: item.label, children: item.label })) : (_jsx("span", { className: "breadcrumb-current", children: item.label })) })] }, item.href ?? `${item.label}-${i}`));
|
|
73
|
+
}) }) }), structured && (_jsx("script", { type: "application/ld+json", dangerouslySetInnerHTML: { __html: JSON.stringify({
|
|
74
|
+
'@context': 'https://schema.org',
|
|
75
|
+
'@type': 'BreadcrumbList',
|
|
76
|
+
itemListElement: items.map((item, i) => ({
|
|
77
|
+
'@type': 'ListItem',
|
|
78
|
+
position: i + 1,
|
|
79
|
+
name: item.label,
|
|
80
|
+
...(item.href ? { item: absolute(item.href) } : {}),
|
|
81
|
+
})),
|
|
82
|
+
}) } }))] }));
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The standard page-top row: the trail, plus optional right-aligned actions.
|
|
86
|
+
*
|
|
87
|
+
* The column it sits in is the one its route declares — the row reads the
|
|
88
|
+
* page's own max-width by inheritance, so a trail can no longer disagree with
|
|
89
|
+
* the content it titles.
|
|
90
|
+
*/
|
|
91
|
+
export function BreadcrumbsRow({ actions, className = '', ...props }) {
|
|
92
|
+
return (_jsxs("div", { className: `breadcrumbs-row ${actions ? 'spread' : ''} ${className}`.trim(), children: [_jsx(Breadcrumbs, { ...props }), actions] }));
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* The sequential read at the foot of an article — the move the infobox rail's
|
|
96
|
+
* lateral links do not cover.
|
|
97
|
+
*
|
|
98
|
+
* Ordering is entirely the caller's; pair this with `adjacentPages` from
|
|
99
|
+
* `wiki-formant/pagination` over a list you already hold. Both wikis had this
|
|
100
|
+
* markup and had already drifted on the parts that matter rather than the parts
|
|
101
|
+
* that show: one carried `rel="prev"`/`rel="next"` and an `aria-label` and the
|
|
102
|
+
* other carried neither, and the one without expressed its right-hand alignment
|
|
103
|
+
* as two inline utilities instead of the modifier its own stylesheet defines.
|
|
104
|
+
*
|
|
105
|
+
* The `page-nav__*` class names are NOT props, for the reason `WikiRail`'s are
|
|
106
|
+
* not: they are the convention both stylesheets already implement, and making
|
|
107
|
+
* them configurable is how a convention forks. The empty `<div>` holds the
|
|
108
|
+
* first article's left column so the next link stays in the right one.
|
|
109
|
+
*/
|
|
110
|
+
export function PageNav({ prev, next, link: Link = Anchor, label = 'Article navigation', prevLabel = 'Previous', nextLabel = 'Next', prevGlyph = '\u2190', nextGlyph = '\u2192', }) {
|
|
111
|
+
if (!prev && !next)
|
|
112
|
+
return null;
|
|
113
|
+
return (_jsxs("nav", { className: "page-nav", "aria-label": label, children: [prev ? (_jsxs(Link, { href: prev.href, className: "page-nav-link", rel: "prev", children: [_jsxs("span", { className: "page-nav-label", children: [prevGlyph, prevLabel] }), _jsx("span", { className: "page-nav-title", children: prev.title })] })) : (_jsx("div", {})), next && (_jsxs(Link, { href: next.href, className: "page-nav-link page-nav-link--end", rel: "next", children: [_jsxs("span", { className: "page-nav-label page-nav-label--end", children: [nextLabel, nextGlyph] }), _jsx("span", { className: "page-nav-title", children: next.title })] }))] }));
|
|
61
114
|
}
|
|
62
|
-
//# sourceMappingURL=react-server.js.map
|
package/dist/react.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { WikiLinkComponent } from './react-server.js';
|
|
2
1
|
import { type ComboboxAria } from './combobox.js';
|
|
3
2
|
import { Component, type CSSProperties, type KeyboardEvent, type ReactNode } from 'react';
|
|
4
3
|
export interface SidebarOptions {
|
|
@@ -307,60 +306,50 @@ export declare class ErrorBoundary extends Component<{
|
|
|
307
306
|
componentDidCatch(error: unknown): void;
|
|
308
307
|
render(): ReactNode;
|
|
309
308
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
href: string;
|
|
313
|
-
title: string;
|
|
314
|
-
glyph: string;
|
|
315
|
-
blurb?: string;
|
|
316
|
-
}
|
|
317
|
-
export interface WikiRailProps {
|
|
318
|
-
/**
|
|
319
|
-
* The router's link component.
|
|
320
|
-
*
|
|
321
|
-
* The rail takes it as a prop rather than importing one. This package has no
|
|
322
|
-
* `next` peer dependency and is not getting one — but a rail that falls back
|
|
323
|
-
* to a bare `<a>` turns every navigation into a full page load, which is the
|
|
324
|
-
* whole reason a wiki has a persistent rail. So the router stays the
|
|
325
|
-
* consumer's and arrives through the door.
|
|
326
|
-
*/
|
|
327
|
-
link: WikiLinkComponent;
|
|
328
|
-
/** The path being rendered, for the active marker. */
|
|
329
|
-
activePath: string;
|
|
330
|
-
/** The wiki root's href. */
|
|
331
|
-
homeHref: string;
|
|
332
|
-
/** The wiki's sections with their hrefs already built, resolved server-side. */
|
|
333
|
-
sections: RailSection[];
|
|
309
|
+
export interface RailShellProps {
|
|
310
|
+
children: ReactNode;
|
|
334
311
|
/**
|
|
335
|
-
*
|
|
312
|
+
* Class prefix the stylesheet implements: `"wiki-sidebar"` or `"sidebar"`.
|
|
336
313
|
*
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
314
|
+
* The one thing genuinely per-repo here. Everything else — which three states
|
|
315
|
+
* exist, what each means, and that the attribute outranks the class — is a
|
|
316
|
+
* contract both stylesheets already spell out in near-identical comments.
|
|
340
317
|
*/
|
|
341
|
-
|
|
318
|
+
prefix: string;
|
|
319
|
+
/** Accessible name. A rail with none is an unlabelled landmark. */
|
|
342
320
|
label?: string;
|
|
343
|
-
|
|
344
|
-
homeLabel?: string;
|
|
345
|
-
homeGlyph?: string;
|
|
346
|
-
sectionsLabel?: string;
|
|
347
|
-
tocLabel?: string;
|
|
321
|
+
className?: string;
|
|
348
322
|
}
|
|
349
323
|
/**
|
|
350
|
-
* The
|
|
324
|
+
* The collapsible rail's outer shell: the landmark, its three states, and the
|
|
325
|
+
* scroll container, with a tap inside it closing the rail on mobile.
|
|
326
|
+
*
|
|
327
|
+
* THE THREE STATES ARE NOT TWO. `--open` / `--closed` is the reader's choice;
|
|
328
|
+
* `--instant` suppresses the transition until that choice has been read out of
|
|
329
|
+
* storage. Without the third, a rail the reader left closed renders open and
|
|
330
|
+
* then *slides shut* on every single load — and because the fix is invisible
|
|
331
|
+
* once it works, it is the part a reimplementation drops. Both rails that had
|
|
332
|
+
* this written out locally carried the same paragraph of comment explaining it,
|
|
333
|
+
* which is how you can tell it was learned twice.
|
|
334
|
+
*
|
|
335
|
+
* The class is not authoritative and cannot be: the server cannot read
|
|
336
|
+
* localStorage, so `sidebarBootScript` stamps `html[data-sidebar]` before first
|
|
337
|
+
* paint and the stylesheet lets that attribute win. The class is what keeps
|
|
338
|
+
* React's view in sync afterwards.
|
|
351
339
|
*
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
*
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
*
|
|
340
|
+
* Closing on navigate is scoped to mobile because that is where the rail
|
|
341
|
+
* OVERLAYS the article — on a desktop it is a column beside it, and collapsing
|
|
342
|
+
* it on every click would be a rail that folds itself away as you use it.
|
|
343
|
+
*/
|
|
344
|
+
export declare function RailShell({ children, prefix, label, className }: RailShellProps): import("react").JSX.Element;
|
|
345
|
+
/**
|
|
346
|
+
* Is this rail link the one the reader is on?
|
|
359
347
|
*
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
*
|
|
348
|
+
* `tree` marks a link that owns its descendants — a section that should stay lit
|
|
349
|
+
* while you read a page inside it. Both rails had this predicate and both
|
|
350
|
+
* matched on the PATH ONLY, deliberately: `?edit=` and `?history=` are modes a
|
|
351
|
+
* page enters, not destinations a rail selects, and reading them would drag
|
|
352
|
+
* `useSearchParams` into a statically-rendered wiki.
|
|
363
353
|
*/
|
|
364
|
-
export declare function
|
|
354
|
+
export declare function isRailLinkActive(activePath: string, href: string, tree?: boolean): boolean;
|
|
365
355
|
export type { WikiLinkComponent, WikiLinkProps } from './react-server.js';
|
|
366
|
-
//# sourceMappingURL=react.d.ts.map
|
package/dist/react.js
CHANGED
|
@@ -574,30 +574,51 @@ export class ErrorBoundary extends Component {
|
|
|
574
574
|
}
|
|
575
575
|
}
|
|
576
576
|
/**
|
|
577
|
-
* The
|
|
577
|
+
* The collapsible rail's outer shell: the landmark, its three states, and the
|
|
578
|
+
* scroll container, with a tap inside it closing the rail on mobile.
|
|
578
579
|
*
|
|
579
|
-
*
|
|
580
|
-
*
|
|
581
|
-
*
|
|
582
|
-
*
|
|
583
|
-
*
|
|
584
|
-
*
|
|
585
|
-
*
|
|
580
|
+
* THE THREE STATES ARE NOT TWO. `--open` / `--closed` is the reader's choice;
|
|
581
|
+
* `--instant` suppresses the transition until that choice has been read out of
|
|
582
|
+
* storage. Without the third, a rail the reader left closed renders open and
|
|
583
|
+
* then *slides shut* on every single load — and because the fix is invisible
|
|
584
|
+
* once it works, it is the part a reimplementation drops. Both rails that had
|
|
585
|
+
* this written out locally carried the same paragraph of comment explaining it,
|
|
586
|
+
* which is how you can tell it was learned twice.
|
|
586
587
|
*
|
|
587
|
-
*
|
|
588
|
-
*
|
|
589
|
-
*
|
|
588
|
+
* The class is not authoritative and cannot be: the server cannot read
|
|
589
|
+
* localStorage, so `sidebarBootScript` stamps `html[data-sidebar]` before first
|
|
590
|
+
* paint and the stylesheet lets that attribute win. The class is what keeps
|
|
591
|
+
* React's view in sync afterwards.
|
|
592
|
+
*
|
|
593
|
+
* Closing on navigate is scoped to mobile because that is where the rail
|
|
594
|
+
* OVERLAYS the article — on a desktop it is a column beside it, and collapsing
|
|
595
|
+
* it on every click would be a rail that folds itself away as you use it.
|
|
596
|
+
*/
|
|
597
|
+
export function RailShell({ children, prefix, label, className }) {
|
|
598
|
+
const { open, setOpen, isMobile, ready } = useSidebar();
|
|
599
|
+
const close = useCallback(() => {
|
|
600
|
+
if (isMobile)
|
|
601
|
+
setOpen(false);
|
|
602
|
+
}, [isMobile, setOpen]);
|
|
603
|
+
const classes = [
|
|
604
|
+
prefix,
|
|
605
|
+
open ? `${prefix}--open` : `${prefix}--closed`,
|
|
606
|
+
ready ? '' : `${prefix}--instant`,
|
|
607
|
+
className ?? '',
|
|
608
|
+
]
|
|
609
|
+
.filter(Boolean)
|
|
610
|
+
.join(' ');
|
|
611
|
+
return (_jsx("aside", { className: classes, "aria-label": label, children: _jsx("div", { className: `${prefix}__scroll`, onClick: close, children: children }) }));
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Is this rail link the one the reader is on?
|
|
615
|
+
*
|
|
616
|
+
* `tree` marks a link that owns its descendants — a section that should stay lit
|
|
617
|
+
* while you read a page inside it. Both rails had this predicate and both
|
|
618
|
+
* matched on the PATH ONLY, deliberately: `?edit=` and `?history=` are modes a
|
|
619
|
+
* page enters, not destinations a rail selects, and reading them would drag
|
|
620
|
+
* `useSearchParams` into a statically-rendered wiki.
|
|
590
621
|
*/
|
|
591
|
-
export function
|
|
592
|
-
|
|
593
|
-
const item = (href, active) => `wiki-rail__item${active ? ' wiki-rail__item--active' : ''}`;
|
|
594
|
-
return (_jsxs("aside", { className: "wiki-sidebar", "aria-label": label, children: [_jsxs("button", { type: "button", className: "wiki-rail__toggle", onClick: toggle, "aria-expanded": open, children: [_jsx("span", { className: "wiki-rail__glyph", "aria-hidden": true, children: open ? '▾' : '▸' }), toggleLabel] }), _jsxs("div", { className: "wiki-rail__scroll", children: [_jsx("nav", { className: "wiki-rail__group", children: _jsxs(Link, { href: homeHref, className: item(homeHref, activePath === homeHref), children: [_jsx("span", { className: "wiki-rail__glyph", "aria-hidden": true, children: homeGlyph }), homeLabel] }) }), _jsx(TableOfContents, { headings: headings.map(h => ({ id: h.id, text: h.text, level: h.level })), indentRem: 0, offsetVar: "--spacing-lg", offsetFallback: 24, classNames: {
|
|
595
|
-
root: 'wiki-rail__group wiki-rail__group--toc',
|
|
596
|
-
button: 'wiki-rail__toc-btn',
|
|
597
|
-
label: 'wiki-rail__label',
|
|
598
|
-
list: 'wiki-rail__toc-list',
|
|
599
|
-
item: 'wiki-rail__toc-item',
|
|
600
|
-
itemActive: 'wiki-rail__toc-item--active',
|
|
601
|
-
}, label: tocLabel }), _jsxs("nav", { className: "wiki-rail__group", "aria-label": sectionsLabel, children: [_jsx("span", { className: "wiki-rail__label", children: sectionsLabel }), sections.map(section => (_jsxs(Link, { href: section.href, title: section.blurb, className: item(section.href, activePath === section.href || activePath.startsWith(`${section.href}/`)), children: [_jsx("span", { className: "wiki-rail__glyph", "aria-hidden": true, children: section.glyph }), section.title] }, section.href)))] })] })] }));
|
|
622
|
+
export function isRailLinkActive(activePath, href, tree = false) {
|
|
623
|
+
return tree ? activePath === href || activePath.startsWith(`${href}/`) : activePath === href;
|
|
602
624
|
}
|
|
603
|
-
//# sourceMappingURL=react.js.map
|
package/dist/revisions.d.ts
CHANGED
package/dist/revisions.js
CHANGED
package/dist/rola.d.ts
CHANGED
package/dist/rola.js
CHANGED
package/dist/seeded.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** djb2-ish, 32-bit, non-negative. Stable across processes and runtimes. */
|
|
2
|
+
export declare function hashStr(s: string): number;
|
|
3
|
+
/**
|
|
4
|
+
* Lehmer/Park-Miller, seeded by an integer.
|
|
5
|
+
*
|
|
6
|
+
* Both guards matter and neither is obvious. Without the modulo a seed can
|
|
7
|
+
* exceed the modulus; without the `<= 0` correction a seed of 0 sticks the
|
|
8
|
+
* generator at 0 forever — every call returns the same number and whatever it
|
|
9
|
+
* was laying out degenerates to a single point.
|
|
10
|
+
*/
|
|
11
|
+
export declare function seededRandom(seed: number): () => number;
|
package/dist/seeded.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// seeded.ts — deterministic pseudo-randomness, for art that must not move.
|
|
2
|
+
//
|
|
3
|
+
// Both wikis generate SVG from a title: a page banner, a fallback icon. The
|
|
4
|
+
// mark has to be identical on the server and in the browser and on the next
|
|
5
|
+
// render forever, so `Math.random` is not available to them and these two are
|
|
6
|
+
// what they use instead. Both had written the same pair, and the comment in one
|
|
7
|
+
// of them recorded that its two guards had been ported from the other — which
|
|
8
|
+
// is a copy documenting itself as a copy.
|
|
9
|
+
/** djb2-ish, 32-bit, non-negative. Stable across processes and runtimes. */
|
|
10
|
+
export function hashStr(s) {
|
|
11
|
+
let h = 0;
|
|
12
|
+
for (let i = 0; i < s.length; i++)
|
|
13
|
+
h = ((h << 5) - h + s.charCodeAt(i)) | 0;
|
|
14
|
+
return Math.abs(h);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Lehmer/Park-Miller, seeded by an integer.
|
|
18
|
+
*
|
|
19
|
+
* Both guards matter and neither is obvious. Without the modulo a seed can
|
|
20
|
+
* exceed the modulus; without the `<= 0` correction a seed of 0 sticks the
|
|
21
|
+
* generator at 0 forever — every call returns the same number and whatever it
|
|
22
|
+
* was laying out degenerates to a single point.
|
|
23
|
+
*/
|
|
24
|
+
export function seededRandom(seed) {
|
|
25
|
+
let s = seed % 2147483647;
|
|
26
|
+
if (s <= 0)
|
|
27
|
+
s += 2147483646;
|
|
28
|
+
return () => {
|
|
29
|
+
s = (s * 16807) % 2147483647;
|
|
30
|
+
return s / 2147483647;
|
|
31
|
+
};
|
|
32
|
+
}
|
package/dist/sidebar.d.ts
CHANGED
package/dist/sidebar.js
CHANGED
|
@@ -40,4 +40,3 @@ export function sidebarBootScript(storageKey = 'wiki:sidebar', breakpoint = 1024
|
|
|
40
40
|
`var o=v===null?!window.matchMedia("(max-width: ${breakpoint - 1}px)").matches:v==="1";` +
|
|
41
41
|
`document.documentElement.setAttribute(${JSON.stringify(SIDEBAR_ATTRIBUTE)},o?"open":"closed");}catch(e){}})()`);
|
|
42
42
|
}
|
|
43
|
-
//# sourceMappingURL=sidebar.js.map
|
package/dist/taxonomy.d.ts
CHANGED
|
@@ -161,4 +161,3 @@ export interface Taxonomy {
|
|
|
161
161
|
rankRelated: <T extends FacetablePage>(page: T, siblings: T[], tagPath: string, limit?: number) => RelatedRanking<T>;
|
|
162
162
|
}
|
|
163
163
|
export declare function createTaxonomy(config: TaxonomyConfig): Taxonomy;
|
|
164
|
-
//# sourceMappingURL=taxonomy.d.ts.map
|
package/dist/taxonomy.js
CHANGED
package/dist/text.d.ts
CHANGED
|
@@ -13,6 +13,20 @@ export type BannerVariant = 'stub' | 'unsourced' | 'outdated' | 'promotional' |
|
|
|
13
13
|
* the markdown twin and the MDX export all render the same six strings.
|
|
14
14
|
*/
|
|
15
15
|
export declare const BANNER_LABELS: Record<BannerVariant, string>;
|
|
16
|
+
/**
|
|
17
|
+
* The banner variants as an editor's option list, in the order a writer meets
|
|
18
|
+
* them: the two that describe a gap first, then the three that describe a flaw.
|
|
19
|
+
*
|
|
20
|
+
* Derived from `BANNER_LABELS` rather than restated. Both editors had typed the
|
|
21
|
+
* same six `{ value, label }` pairs out by hand, which made four places in the
|
|
22
|
+
* workspace holding the same strings — and an editor whose dropdown disagrees
|
|
23
|
+
* with the renderer's label is a page whose banner changes wording when you
|
|
24
|
+
* open it for editing.
|
|
25
|
+
*/
|
|
26
|
+
export declare const BANNER_VARIANTS: ReadonlyArray<{
|
|
27
|
+
value: BannerVariant;
|
|
28
|
+
label: string;
|
|
29
|
+
}>;
|
|
16
30
|
/** A maintenance notice, inline: `[Notice: Needs citations] …`. */
|
|
17
31
|
export declare function bannerToText(label: string, text?: string | null): string;
|
|
18
32
|
/** Each tab under its label, tags stripped — highlighted markup is noise here. */
|
|
@@ -38,4 +52,3 @@ export declare function collectText(node: unknown, out?: string[]): string[];
|
|
|
38
52
|
* than a failure: title-only hits are how the top tiers match.
|
|
39
53
|
*/
|
|
40
54
|
export declare function matchSnippet(blocks: unknown, query: string, opening: () => string, maxLen?: number): string;
|
|
41
|
-
//# sourceMappingURL=text.d.ts.map
|
package/dist/text.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// As in `blocks.ts`, the dispatch stays with the caller — a `switch` over its
|
|
8
8
|
// own block union, where a new type is a compile error until it is handled —
|
|
9
9
|
// and only the bodies live here.
|
|
10
|
-
import { decodeEntities } from './
|
|
10
|
+
import { decodeEntities } from './markdown.js';
|
|
11
11
|
/**
|
|
12
12
|
* HTML to readable text. Links keep their href in parentheses so a model can
|
|
13
13
|
* still follow a citation; block-level tags become newlines; list items get a
|
|
@@ -36,6 +36,20 @@ export const BANNER_LABELS = {
|
|
|
36
36
|
cleanup: 'Needs cleanup',
|
|
37
37
|
coi: 'Conflict of interest',
|
|
38
38
|
};
|
|
39
|
+
/**
|
|
40
|
+
* The banner variants as an editor's option list, in the order a writer meets
|
|
41
|
+
* them: the two that describe a gap first, then the three that describe a flaw.
|
|
42
|
+
*
|
|
43
|
+
* Derived from `BANNER_LABELS` rather than restated. Both editors had typed the
|
|
44
|
+
* same six `{ value, label }` pairs out by hand, which made four places in the
|
|
45
|
+
* workspace holding the same strings — and an editor whose dropdown disagrees
|
|
46
|
+
* with the renderer's label is a page whose banner changes wording when you
|
|
47
|
+
* open it for editing.
|
|
48
|
+
*/
|
|
49
|
+
export const BANNER_VARIANTS = Object.keys(BANNER_LABELS).map(value => ({
|
|
50
|
+
value,
|
|
51
|
+
label: BANNER_LABELS[value],
|
|
52
|
+
}));
|
|
39
53
|
/** A maintenance notice, inline: `[Notice: Needs citations] …`. */
|
|
40
54
|
export function bannerToText(label, text) {
|
|
41
55
|
return `[Notice: ${label}]${text ? ' ' + stripHtml(text) : ''}`;
|
|
@@ -109,4 +123,3 @@ export function matchSnippet(blocks, query, opening, maxLen = 200) {
|
|
|
109
123
|
const end = Math.min(text.length, start + maxLen);
|
|
110
124
|
return `${start > 0 ? '…' : ''}${text.slice(start, end).trimEnd()}${end < text.length ? '…' : ''}`;
|
|
111
125
|
}
|
|
112
|
-
//# sourceMappingURL=text.js.map
|
package/dist/tiptap.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
2
|
import { Node as TiptapNode } from '@tiptap/core';
|
|
3
|
+
/** Local `cn`. Both wikis import one; the package will not depend on one. */
|
|
3
4
|
export declare const Iframe: TiptapNode<any, any>;
|
|
4
5
|
/** The stock extension plus the paste rule it does not ship with. */
|
|
5
6
|
export declare const YouTube: TiptapNode<import("@tiptap/extension-youtube").YoutubeOptions, any>;
|
|
@@ -75,4 +76,3 @@ export declare function createTabs({ classNames, icons, tabLabel, }?: TabsOption
|
|
|
75
76
|
TabGroup: TiptapNode<any, any>;
|
|
76
77
|
TabItem: TiptapNode<any, any>;
|
|
77
78
|
};
|
|
78
|
-
//# sourceMappingURL=tiptap.d.ts.map
|
package/dist/tiptap.js
CHANGED
|
@@ -24,8 +24,8 @@ import TiptapCodeBlock from '@tiptap/extension-code-block';
|
|
|
24
24
|
import { onTweetResize, tweetEmbedSrc } from './dom.js';
|
|
25
25
|
import { toMapEmbedUrl } from './maps.js';
|
|
26
26
|
import { useClickOutside } from './react.js';
|
|
27
|
+
import { cx } from './html.js';
|
|
27
28
|
/** Local `cn`. Both wikis import one; the package will not depend on one. */
|
|
28
|
-
const cx = (...parts) => parts.filter(Boolean).join(' ');
|
|
29
29
|
// ---- iframe -----------------------------------------------------------------
|
|
30
30
|
export const Iframe = TiptapNode.create({
|
|
31
31
|
name: 'iframe',
|
|
@@ -341,4 +341,3 @@ export function createTabs({ classNames = {}, icons = {}, tabLabel = i => `Tab $
|
|
|
341
341
|
});
|
|
342
342
|
return { TabGroup, TabItem };
|
|
343
343
|
}
|
|
344
|
-
//# sourceMappingURL=tiptap.js.map
|
package/dist/validation.d.ts
CHANGED
|
@@ -12,9 +12,9 @@ export declare function safeLinkHref(raw: string | null | undefined): string | n
|
|
|
12
12
|
/** An author-supplied URL is fine iff it is empty (unset) or resolves safely. */
|
|
13
13
|
export declare const okUrl: (u: unknown) => boolean;
|
|
14
14
|
/** `[{ id, text, url? }]` — the shape a references block stores. */
|
|
15
|
-
export declare function validateReferenceItems(items: unknown
|
|
15
|
+
export declare function validateReferenceItems(items: unknown): boolean;
|
|
16
16
|
/** `[{ id, heading, links: [{ label, href }] }]` — a link-grid block's groups. */
|
|
17
|
-
export declare function validateLinkGroups(groups: unknown
|
|
17
|
+
export declare function validateLinkGroups(groups: unknown): boolean;
|
|
18
18
|
export interface BlockValidatorOptions {
|
|
19
19
|
/** True for a type this wiki knows at all. */
|
|
20
20
|
isKnownType: (type: string) => boolean;
|
|
@@ -44,4 +44,3 @@ export declare function duplicateBlockIds<B extends {
|
|
|
44
44
|
type: string;
|
|
45
45
|
id: string;
|
|
46
46
|
}>(block: B, newId: () => string): B;
|
|
47
|
-
//# sourceMappingURL=validation.d.ts.map
|