@ubx/docs-ui 0.1.0 → 0.4.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/dist/Footer.d.ts +9 -1
- package/dist/Footer.js +21 -6
- package/dist/Header.d.ts +11 -1
- package/dist/Header.js +2 -2
- package/dist/MobileSidebarToggle.d.ts +6 -1
- package/dist/MobileSidebarToggle.js +25 -10
- package/dist/PageShell.d.ts +54 -0
- package/dist/PageShell.js +33 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/theme-a.d.ts +1 -1
- package/dist/theme-a.js +33 -0
- package/package.json +20 -8
package/dist/Footer.d.ts
CHANGED
|
@@ -1 +1,9 @@
|
|
|
1
|
-
export declare function Footer(
|
|
1
|
+
export declare function Footer({ tagline, links, }: {
|
|
2
|
+
/** The one-line statement of what this particular site's content is. */
|
|
3
|
+
tagline: React.ReactNode;
|
|
4
|
+
/** Footer destinations, stated per site rather than shared. */
|
|
5
|
+
links: {
|
|
6
|
+
label: string;
|
|
7
|
+
href: string;
|
|
8
|
+
}[];
|
|
9
|
+
}): import("react").JSX.Element;
|
package/dist/Footer.js
CHANGED
|
@@ -2,10 +2,25 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
// Footer: Material style, a hairline divider and quiet text, not a
|
|
3
3
|
// heavy block -- the same restrained treatment already established
|
|
4
4
|
// for hairline dividers site-wide (globals.css's own --color-border).
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
//
|
|
6
|
+
// IDENTITY IS A PROP, NOT A DEFAULT, for the same reason it is on
|
|
7
|
+
// GlobalSearch, and this component is the proof that the reason is real.
|
|
8
|
+
//
|
|
9
|
+
// Extracted with the provider site's own identity hardcoded: a tagline
|
|
10
|
+
// reading "Reference content is generated from each provider's own real
|
|
11
|
+
// schema, not hand-written" and a License link pointing at
|
|
12
|
+
// ubx-docs-providers. Both were correct for the site they came from and
|
|
13
|
+
// silently wrong on the user docs site, where all 137 pages are
|
|
14
|
+
// hand-written MDX and the repo is a different one. The tagline did not
|
|
15
|
+
// merely fail to apply, it asserted the exact opposite of the truth on
|
|
16
|
+
// every page of the site.
|
|
17
|
+
//
|
|
18
|
+
// GlobalSearch was caught during extraction because its regression was
|
|
19
|
+
// visible (a pill turned into a rectangle). This one was not, because
|
|
20
|
+
// wrong prose looks exactly like right prose until someone reads it. So
|
|
21
|
+
// the rule cannot be "check carefully during extraction"; it has to be
|
|
22
|
+
// that the type system refuses to let a site inherit an identity it did
|
|
23
|
+
// not state. Hence both props are required and neither has a default.
|
|
24
|
+
export function Footer({ tagline, links, }) {
|
|
25
|
+
return (_jsx("footer", { className: "border-t border-border", children: _jsxs("div", { className: "mx-auto max-w-7xl px-6 py-8 text-sm text-foreground-muted", children: [_jsxs("div", { className: "flex flex-col items-center gap-3 sm:flex-row sm:justify-between", children: [_jsx("p", { children: tagline }), _jsx("nav", { className: "flex items-center gap-5", children: links.map((l) => (_jsx("a", { href: l.href, className: "hover:text-primary", children: l.label }, l.href))) })] }), _jsx("p", { className: "mt-4 text-center text-xs sm:text-left", children: "\u00A9 2026 Ubiquex" })] }) }));
|
|
11
26
|
}
|
package/dist/Header.d.ts
CHANGED
|
@@ -8,11 +8,21 @@ export type SectionTab = {
|
|
|
8
8
|
label: string;
|
|
9
9
|
href: string;
|
|
10
10
|
};
|
|
11
|
-
export declare function Header({ nav, tabs, activeTab, mobileMenu, }: {
|
|
11
|
+
export declare function Header({ nav, tabs, activeTab, mobileMenu, search, }: {
|
|
12
12
|
nav: NavLink[];
|
|
13
13
|
/** Omit entirely for a single-tier header, which is the provider site. */
|
|
14
14
|
tabs?: SectionTab[];
|
|
15
15
|
/** href of the active tab, matched by prefix so nested pages stay lit. */
|
|
16
16
|
activeTab?: string;
|
|
17
17
|
mobileMenu?: React.ReactNode;
|
|
18
|
+
/**
|
|
19
|
+
* Search control, rendered to the left of the theme toggle.
|
|
20
|
+
*
|
|
21
|
+
* In the header rather than in page content because the alternative
|
|
22
|
+
* put it on exactly one page type per site: the provider site's home
|
|
23
|
+
* page, and the user docs site's section landing pages, which are the
|
|
24
|
+
* pages being removed. Every content page on both sites had no way to
|
|
25
|
+
* search at all.
|
|
26
|
+
*/
|
|
27
|
+
search?: React.ReactNode;
|
|
18
28
|
}): import("react").JSX.Element;
|
package/dist/Header.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import Link from "next/link";
|
|
3
3
|
import { ThemeToggle } from "./ThemeToggle";
|
|
4
|
-
export function Header({ nav, tabs, activeTab, mobileMenu, }) {
|
|
4
|
+
export function Header({ nav, tabs, activeTab, mobileMenu, search, }) {
|
|
5
5
|
return (_jsxs("header", { className: "border-b border-border bg-background", children: [_jsxs("div", { className: "relative mx-auto flex max-w-7xl items-center gap-3 px-6 py-4", children: [mobileMenu, _jsxs(Link, { href: "/", className: "flex shrink-0 items-center", children: [_jsx("img", { src: "/logo/logo.png", alt: "ubx", className: "logo-light h-6 w-auto" }), _jsx("img", { src: "/logo/logo-dark.png", alt: "ubx", className: "logo-dark h-6 w-auto" })] }), _jsx("div", { className: "flex-1" }), _jsx("nav", { className: "absolute left-1/2 hidden -translate-x-1/2 items-center gap-5 md:flex", children: nav.map((item) => {
|
|
6
6
|
const className = item.current
|
|
7
7
|
? "text-sm text-primary"
|
|
8
8
|
: "text-sm text-foreground-muted hover:text-primary";
|
|
9
9
|
return item.href.startsWith("/") ? (_jsx(Link, { href: item.href, className: className, children: item.label }, item.label)) : (_jsx("a", { href: item.href, className: className, children: item.label }, item.label));
|
|
10
|
-
}) }), _jsx(ThemeToggle, {})] }), tabs && tabs.length > 0 ? (_jsx("div", { className: "mx-auto max-w-7xl px-6", children: _jsx("nav", { className: "flex gap-6 overflow-x-auto", children: tabs.map((tab) => {
|
|
10
|
+
}) }), search ? _jsx("div", { className: "w-40 shrink-0 sm:w-56 lg:w-64", children: search }) : null, _jsx(ThemeToggle, {})] }), tabs && tabs.length > 0 ? (_jsx("div", { className: "mx-auto max-w-7xl px-6", children: _jsx("nav", { className: "flex gap-6 overflow-x-auto", children: tabs.map((tab) => {
|
|
11
11
|
// Prefix match, so /concepts/ledger keeps the Concepts tab
|
|
12
12
|
// lit rather than only the exact section index.
|
|
13
13
|
const active = activeTab === tab.href || activeTab?.startsWith(tab.href + "/");
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
-
export declare function MobileSidebarToggle({ children }: {
|
|
1
|
+
export declare function MobileSidebarToggle({ children, label, }: {
|
|
2
2
|
children: React.ReactNode;
|
|
3
|
+
/**
|
|
4
|
+
* What this drawer contains, in the consuming site's own vocabulary.
|
|
5
|
+
* Used as the drawer heading and as the basis for both aria-labels.
|
|
6
|
+
*/
|
|
7
|
+
label: string;
|
|
3
8
|
}): import("react").JSX.Element;
|
|
@@ -18,14 +18,29 @@ import { useEffect, useRef, useState } from "react";
|
|
|
18
18
|
// vanishing the instant the tap registers.
|
|
19
19
|
const TRANSITION_MS = 200;
|
|
20
20
|
// UBI-247: takes the drawer contents as `children` rather than
|
|
21
|
-
// constructing a ProviderSidebar itself.
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
|
|
21
|
+
// constructing a ProviderSidebar itself. The provider site passes
|
|
22
|
+
// <ProviderSidebar .../>, this site passes <DocSidebar .../>, and the
|
|
23
|
+
// open/close/transition/route-change behaviour below is identical for
|
|
24
|
+
// both.
|
|
25
|
+
//
|
|
26
|
+
// This comment used to claim that the `children` coupling "was the one
|
|
27
|
+
// thing in this component that was not generic." That was wrong, and it
|
|
28
|
+
// is left recorded here rather than quietly deleted because the way it
|
|
29
|
+
// was wrong is the useful part. Three strings a few lines below still
|
|
30
|
+
// said "Services" and "service navigation", which is AWS provider
|
|
31
|
+
// vocabulary: the provider site's mobile drawer holds a provider's
|
|
32
|
+
// service groups. The user docs site's drawer holds documentation
|
|
33
|
+
// pages, so it announced the wrong thing to every mobile reader and to
|
|
34
|
+
// every screen reader.
|
|
35
|
+
//
|
|
36
|
+
// It survived because the extraction was audited per component by
|
|
37
|
+
// reading each one, and reading is exactly what does not catch a
|
|
38
|
+
// plausible-sounding noun. It was found later by mechanically
|
|
39
|
+
// extracting every user-visible string literal in the package and
|
|
40
|
+
// asking of each one whether it could be true on both sites. `label` is
|
|
41
|
+
// required for the same reason Footer's props are: a default here is a
|
|
42
|
+
// silent claim about which site you are.
|
|
43
|
+
export function MobileSidebarToggle({ children, label, }) {
|
|
29
44
|
const [mounted, setMounted] = useState(false);
|
|
30
45
|
const [visible, setVisible] = useState(false);
|
|
31
46
|
const closeTimer = useRef(null);
|
|
@@ -68,8 +83,8 @@ export function MobileSidebarToggle({ children }) {
|
|
|
68
83
|
close();
|
|
69
84
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
70
85
|
}, [pathname]);
|
|
71
|
-
return (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: open, "aria-label":
|
|
86
|
+
return (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: open, "aria-label": `Open ${label} navigation`, className: "flex h-9 w-9 shrink-0 items-center justify-center rounded text-foreground-muted hover:bg-surface hover:text-primary lg:hidden", children: _jsx("svg", { viewBox: "0 0 20 20", width: "20", height: "20", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M3 5.5h14M3 10h14M3 14.5h14", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round" }) }) }), mounted && (_jsxs("div", { role: "dialog", "aria-modal": "true", className: "fixed inset-0 z-50 lg:hidden", children: [_jsx("button", { type: "button", "aria-label": `Close ${label} navigation`, onClick: close, className: "absolute inset-0 bg-foreground/40 transition-opacity duration-200 motion-reduce:transition-none " +
|
|
72
87
|
(visible ? "opacity-100" : "opacity-0") }), _jsxs("div", { className: "absolute inset-y-0 left-0 flex w-80 max-w-[85vw] flex-col overflow-y-auto bg-background p-4 shadow-lg " +
|
|
73
88
|
"transition-transform duration-200 ease-out motion-reduce:transition-none " +
|
|
74
|
-
(visible ? "translate-x-0" : "-translate-x-full"), children: [_jsxs("div", { className: "mb-3 flex items-center justify-between", children: [_jsx("span", { className: "text-sm font-semibold text-foreground", children:
|
|
89
|
+
(visible ? "translate-x-0" : "-translate-x-full"), children: [_jsxs("div", { className: "mb-3 flex items-center justify-between", children: [_jsx("span", { className: "text-sm font-semibold text-foreground", children: label }), _jsx("button", { type: "button", onClick: close, "aria-label": `Close ${label} navigation`, className: "flex h-8 w-8 items-center justify-center rounded text-foreground-muted hover:bg-surface hover:text-primary", children: _jsx("svg", { viewBox: "0 0 16 16", width: "16", height: "16", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M4 4l8 8M12 4l-8 8", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round" }) }) })] }), children] })] }))] }));
|
|
75
90
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
import { type NavLink, type SectionTab } from "./Header";
|
|
3
|
+
export type PageShellProps = {
|
|
4
|
+
nav: NavLink[];
|
|
5
|
+
/** Omit for a single-tier header. The provider site omits it. */
|
|
6
|
+
tabs?: SectionTab[];
|
|
7
|
+
/** href of the active tab, prefix-matched so nested pages stay lit. */
|
|
8
|
+
activeTab?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Sidebar tree. When present the shell renders the two-column rail and
|
|
11
|
+
* wires the same node into the mobile drawer, so the desktop and mobile
|
|
12
|
+
* navigation can never disagree about what they contain.
|
|
13
|
+
*/
|
|
14
|
+
sidebar?: React.ReactNode;
|
|
15
|
+
/** Drawer heading, in the consuming site's own vocabulary. */
|
|
16
|
+
sidebarLabel?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Search placeholder. Presence of this prop is what mounts search.
|
|
19
|
+
*
|
|
20
|
+
* The placeholder is a prop because it is genuinely site-specific
|
|
21
|
+
* ("Search resources and data sources..." against "Search the docs").
|
|
22
|
+
* The input's styling is NOT a prop, which reverses the decision
|
|
23
|
+
* GlobalSearch made when it was extracted. That decision was right at
|
|
24
|
+
* the time: the two sites styled the box differently, and a default
|
|
25
|
+
* would have silently imposed one site's look on the other. Now that
|
|
26
|
+
* the shell owns the placement, one styling is the correct answer for
|
|
27
|
+
* both, and leaving it configurable would just re-open the drift.
|
|
28
|
+
*/
|
|
29
|
+
searchPlaceholder?: string;
|
|
30
|
+
/** Footer identity. Required for the reason stated on Footer itself. */
|
|
31
|
+
footer: {
|
|
32
|
+
tagline: React.ReactNode;
|
|
33
|
+
links: {
|
|
34
|
+
label: string;
|
|
35
|
+
href: string;
|
|
36
|
+
}[];
|
|
37
|
+
};
|
|
38
|
+
children: React.ReactNode;
|
|
39
|
+
};
|
|
40
|
+
export declare function PageShell({ nav, tabs, activeTab, sidebar, sidebarLabel, searchPlaceholder, footer, children, }: PageShellProps): React.JSX.Element;
|
|
41
|
+
/**
|
|
42
|
+
* Sets data-theme from localStorage before paint.
|
|
43
|
+
*
|
|
44
|
+
* Both sites carried this as a verbatim string constant in their own root
|
|
45
|
+
* layout, which is duplication the package could not see. It has to be an
|
|
46
|
+
* exported string rather than a component because it goes in <head> via
|
|
47
|
+
* dangerouslySetInnerHTML and must run ahead of hydration: a React
|
|
48
|
+
* component would run too late and the reader would see a flash of the
|
|
49
|
+
* OS default before their stored choice applied.
|
|
50
|
+
*
|
|
51
|
+
* Absent or invalid storage leaves no attribute at all, which is exactly
|
|
52
|
+
* "follow the OS".
|
|
53
|
+
*/
|
|
54
|
+
export declare const THEME_INIT_SCRIPT = "(function () {\n try {\n var stored = window.localStorage.getItem(\"ubx-docs-theme\");\n if (stored === \"light\" || stored === \"dark\") {\n document.documentElement.setAttribute(\"data-theme\", stored);\n }\n } catch (e) {}\n})();";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Header } from "./Header";
|
|
3
|
+
import { Footer } from "./Footer";
|
|
4
|
+
import { GlobalSearch } from "./GlobalSearch";
|
|
5
|
+
import { MobileSidebarToggle } from "./MobileSidebarToggle";
|
|
6
|
+
/** Shared header search styling. See searchPlaceholder above. */
|
|
7
|
+
const SEARCH_INPUT_CLASS = "w-full rounded-full bg-field px-4 py-1.5 text-sm text-foreground outline-none " +
|
|
8
|
+
"placeholder:text-foreground-muted focus:ring-2 focus:ring-primary/30";
|
|
9
|
+
export function PageShell({ nav, tabs, activeTab, sidebar, sidebarLabel = "Navigation", searchPlaceholder, footer, children, }) {
|
|
10
|
+
const search = searchPlaceholder ? (_jsx(GlobalSearch, { placeholder: searchPlaceholder, inputClassName: SEARCH_INPUT_CLASS })) : undefined;
|
|
11
|
+
return (_jsxs(_Fragment, { children: [_jsx(Header, { nav: nav, tabs: tabs, activeTab: activeTab, search: search, mobileMenu: sidebar ? (_jsx(MobileSidebarToggle, { label: sidebarLabel, children: sidebar })) : undefined }), sidebar ? (_jsxs("div", { className: "mx-auto flex w-full max-w-7xl flex-1 gap-10 px-6 py-10", children: [_jsx("aside", { className: "hidden w-64 shrink-0 lg:block", children: sidebar }), _jsx("main", { className: "min-w-0 flex-1", children: children })] })) : (_jsx("main", { className: "mx-auto w-full max-w-7xl flex-1 px-6 py-12", children: children })), _jsx(Footer, { tagline: footer.tagline, links: footer.links })] }));
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Sets data-theme from localStorage before paint.
|
|
15
|
+
*
|
|
16
|
+
* Both sites carried this as a verbatim string constant in their own root
|
|
17
|
+
* layout, which is duplication the package could not see. It has to be an
|
|
18
|
+
* exported string rather than a component because it goes in <head> via
|
|
19
|
+
* dangerouslySetInnerHTML and must run ahead of hydration: a React
|
|
20
|
+
* component would run too late and the reader would see a flash of the
|
|
21
|
+
* OS default before their stored choice applied.
|
|
22
|
+
*
|
|
23
|
+
* Absent or invalid storage leaves no attribute at all, which is exactly
|
|
24
|
+
* "follow the OS".
|
|
25
|
+
*/
|
|
26
|
+
export const THEME_INIT_SCRIPT = `(function () {
|
|
27
|
+
try {
|
|
28
|
+
var stored = window.localStorage.getItem("ubx-docs-theme");
|
|
29
|
+
if (stored === "light" || stored === "dark") {
|
|
30
|
+
document.documentElement.setAttribute("data-theme", stored);
|
|
31
|
+
}
|
|
32
|
+
} catch (e) {}
|
|
33
|
+
})();`;
|
package/dist/index.d.ts
CHANGED
|
@@ -8,3 +8,5 @@ export type { SearchEntry } from "./GlobalSearch";
|
|
|
8
8
|
export { ThemeToggle } from "./ThemeToggle";
|
|
9
9
|
export { Footer } from "./Footer";
|
|
10
10
|
export { MobileSidebarToggle } from "./MobileSidebarToggle";
|
|
11
|
+
export { PageShell, THEME_INIT_SCRIPT } from "./PageShell";
|
|
12
|
+
export type { PageShellProps } from "./PageShell";
|
package/dist/index.js
CHANGED
package/dist/theme-a.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ThemeRegistration } from "shiki";
|
|
2
2
|
export declare const themeA: ThemeRegistration;
|
|
3
3
|
/** Languages theme A has been verified against, token by token. */
|
|
4
|
-
export declare const SUPPORTED_LANGS: readonly ["go", "typescript", "python", "bash", "hcl", "json"];
|
|
4
|
+
export declare const SUPPORTED_LANGS: readonly ["go", "typescript", "python", "bash", "hcl", "json", "yaml", "toml", "docker"];
|
|
5
5
|
export type SupportedLang = (typeof SUPPORTED_LANGS)[number];
|
|
6
6
|
export declare function isSupportedLang(lang: string): lang is SupportedLang;
|
package/dist/theme-a.js
CHANGED
|
@@ -87,6 +87,15 @@ export const themeA = {
|
|
|
87
87
|
// when the provider site's rendered code was diffed before and
|
|
88
88
|
// after the swap.
|
|
89
89
|
"variable.other.property",
|
|
90
|
+
// YAML and TOML mapping keys. UBI-247 slice 3: verified against
|
|
91
|
+
// real token output before being written, and the naive
|
|
92
|
+
// assumption was wrong in two ways. YAML keys carry BOTH
|
|
93
|
+
// entity.name.tag.yaml and string.unquoted.plain.out.yaml, so
|
|
94
|
+
// override 1 below (which exists for shell) was silently
|
|
95
|
+
// stripping every key in every CI example to plain. TOML keys
|
|
96
|
+
// are variable.other.key.toml, covered by nothing above.
|
|
97
|
+
"entity.name.tag",
|
|
98
|
+
"variable.other.key.toml",
|
|
90
99
|
],
|
|
91
100
|
settings: { foreground: "var(--color-code-yellow)" },
|
|
92
101
|
},
|
|
@@ -112,6 +121,24 @@ export const themeA = {
|
|
|
112
121
|
scope: ["keyword.operator"],
|
|
113
122
|
settings: { foreground: "var(--color-foreground)" },
|
|
114
123
|
},
|
|
124
|
+
// OVERRIDE 5. The YAML grammar scopes a bare `on` as a boolean
|
|
125
|
+
// constant, not as a key, because YAML 1.1 really does treat `on` as
|
|
126
|
+
// true. In GitHub Actions `on:` is the trigger key and appears in
|
|
127
|
+
// essentially every CI example (25 of 29 YAML fences in these docs
|
|
128
|
+
// are Actions workflows), so leaving it green made one key in every
|
|
129
|
+
// file render as though it were a language keyword while its
|
|
130
|
+
// siblings were yellow.
|
|
131
|
+
//
|
|
132
|
+
// The grammar cannot distinguish the two, so this is a real
|
|
133
|
+
// trade-off rather than a clean fix: a genuine YAML boolean value
|
|
134
|
+
// now renders plain instead of green. Chosen deliberately, because
|
|
135
|
+
// in this corpus `on:` as a key is common and `true`/`false` as a
|
|
136
|
+
// scalar value is rare, and a wrongly-emphasised key is more
|
|
137
|
+
// misleading than an unemphasised boolean.
|
|
138
|
+
{
|
|
139
|
+
scope: ["constant.language.boolean.yaml"],
|
|
140
|
+
settings: { foreground: "var(--color-foreground)" },
|
|
141
|
+
},
|
|
115
142
|
// OVERRIDE 4. TypeScript scopes the arrow of an arrow function as
|
|
116
143
|
// storage.type.function.arrow, which the generic `storage.type` rule
|
|
117
144
|
// above catches and paints green. The hand-rolled tokenizer left it
|
|
@@ -139,6 +166,12 @@ export const SUPPORTED_LANGS = [
|
|
|
139
166
|
"bash",
|
|
140
167
|
"hcl",
|
|
141
168
|
"json",
|
|
169
|
+
// Added UBI-247 slice 3, each verified token by token: yaml (29
|
|
170
|
+
// fences, concentrated in the Integrations section where CI config is
|
|
171
|
+
// the entire subject), toml, and dockerfile.
|
|
172
|
+
"yaml",
|
|
173
|
+
"toml",
|
|
174
|
+
"docker",
|
|
142
175
|
];
|
|
143
176
|
export function isSupportedLang(lang) {
|
|
144
177
|
return SUPPORTED_LANGS.includes(lang);
|
package/package.json
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ubx/docs-ui",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Shared UI for ubx documentation sites: theme A, Shiki-backed CodeBlock, header, search, theme toggle.",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Shared UI for ubx documentation sites: the page shell, theme A, Shiki-backed CodeBlock, header, search, theme toggle.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"files": [
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
8
10
|
"main": "./dist/index.js",
|
|
9
11
|
"types": "./dist/index.d.ts",
|
|
10
12
|
"exports": {
|
|
11
|
-
".": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"default": "./dist/index.js"
|
|
16
|
+
}
|
|
12
17
|
},
|
|
13
18
|
"scripts": {
|
|
14
|
-
"build": "tsc -p tsconfig.json",
|
|
19
|
+
"build": "rm -rf dist && tsc -p tsconfig.json",
|
|
15
20
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
16
|
-
"prepublishOnly": "npm run build"
|
|
21
|
+
"prepublishOnly": "npm run build",
|
|
22
|
+
"test": "node --test \"test/**/*.test.mjs\"",
|
|
23
|
+
"check:package": "npm run build && node scripts/check-package.mjs"
|
|
17
24
|
},
|
|
18
25
|
"peerDependencies": {
|
|
19
26
|
"next": ">=15",
|
|
@@ -32,6 +39,11 @@
|
|
|
32
39
|
"react-dom": "19.2.8",
|
|
33
40
|
"typescript": "^5"
|
|
34
41
|
},
|
|
35
|
-
"publishConfig": {
|
|
36
|
-
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
},
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "git+https://github.com/Ubiquex/ubx-docs-ui.git"
|
|
48
|
+
}
|
|
37
49
|
}
|