@moku-labs/web 1.11.0 → 1.12.1
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/browser.d.mts +72 -1
- package/dist/browser.mjs +29 -14
- package/dist/index.cjs +1137 -23
- package/dist/index.d.cts +93 -2
- package/dist/index.d.mts +93 -2
- package/dist/index.mjs +1139 -26
- package/package.json +1 -1
package/dist/browser.d.mts
CHANGED
|
@@ -1927,7 +1927,7 @@ type DataProvider = {
|
|
|
1927
1927
|
*/
|
|
1928
1928
|
declare const dataPlugin: import("@moku-labs/core").PluginInstance<"data", DataConfig, DataState, DataProvider, {}> & Record<never, never>;
|
|
1929
1929
|
declare namespace types_d_exports {
|
|
1930
|
-
export { Api, Article, ArticleCard, ComputedFields, Config, ContentApiContext, ContentEvents, ContentProvider, ContentProviderState, EmbedFacade, EmbedFacadeProps, EmbedOptions, FileSystemContentOptions, Frontmatter, LoadAllOptions, MermaidDiagramOptions, State };
|
|
1930
|
+
export { Api, Article, ArticleCard, ComputedFields, Config, ContentApiContext, ContentEvents, ContentProvider, ContentProviderState, EmbedFacade, EmbedFacadeProps, EmbedOptions, FileSystemContentOptions, Frontmatter, GalleryComponent, GalleryOptions, GalleryProps, GallerySlide, GalleryTransformOptions, LoadAllOptions, MermaidDiagramOptions, State };
|
|
1931
1931
|
}
|
|
1932
1932
|
/**
|
|
1933
1933
|
* YAML frontmatter parsed from each article file.
|
|
@@ -2120,6 +2120,66 @@ type EmbedOptions = {
|
|
|
2120
2120
|
*/
|
|
2121
2121
|
facade?: EmbedFacade;
|
|
2122
2122
|
};
|
|
2123
|
+
/** One resolved gallery slide handed to a {@link GalleryComponent}. */
|
|
2124
|
+
type GallerySlide = {
|
|
2125
|
+
/** Shared absolute image URL (`/<slug>/<dir>/<file>`), identical from every locale page. */src: string; /** Per-slide alt text (the directive `caption` with a ` · N` index suffix, or just `N`). */
|
|
2126
|
+
alt: string;
|
|
2127
|
+
};
|
|
2128
|
+
/**
|
|
2129
|
+
* Props handed to a `::gallery` component (the swipeable image set the framework
|
|
2130
|
+
* renders to static markup at build time). The framework resolves the directive's
|
|
2131
|
+
* `src` folder to the sorted, URL-rewritten {@link GallerySlide} list; `caption` is
|
|
2132
|
+
* the directive's `caption` attribute; `attributes` is the full raw directive
|
|
2133
|
+
* attribute bag, so a custom component can read arbitrary extra options
|
|
2134
|
+
* (e.g. `::gallery{… layout="dots"}`).
|
|
2135
|
+
*
|
|
2136
|
+
* @example
|
|
2137
|
+
* ```tsx
|
|
2138
|
+
* const Gallery = ({ slides, caption }: GalleryProps) => (
|
|
2139
|
+
* <div class="gallery-track">
|
|
2140
|
+
* {slides.map(s => <img src={s.src} alt={s.alt} />)}
|
|
2141
|
+
* </div>
|
|
2142
|
+
* );
|
|
2143
|
+
* ```
|
|
2144
|
+
*/
|
|
2145
|
+
type GalleryProps = {
|
|
2146
|
+
/** The resolved slides, in folder order. */slides: readonly GallerySlide[]; /** The directive's `caption` attribute (empty string when unset). */
|
|
2147
|
+
caption: string; /** The full raw directive attribute bag (custom options live here). */
|
|
2148
|
+
attributes: Readonly<Record<string, string>>;
|
|
2149
|
+
};
|
|
2150
|
+
/**
|
|
2151
|
+
* A consumer-supplied gallery component: a Preact function component over
|
|
2152
|
+
* {@link GalleryProps}, rendered (at build time, to static markup) as the inner
|
|
2153
|
+
* content — inside the framework-owned `<div data-component="gallery">` that carries
|
|
2154
|
+
* the island hook. Defaults to the built-in `GalleryTrack`.
|
|
2155
|
+
*/
|
|
2156
|
+
type GalleryComponent = FunctionComponent<GalleryProps>;
|
|
2157
|
+
/**
|
|
2158
|
+
* Options for the `::gallery` feature (the `gallery` key of
|
|
2159
|
+
* {@link FileSystemContentOptions}). `gallery: true` uses the default component;
|
|
2160
|
+
* `gallery: { component }` swaps in a consumer Preact component.
|
|
2161
|
+
*
|
|
2162
|
+
* @example
|
|
2163
|
+
* ```ts
|
|
2164
|
+
* fileSystemContent({ contentDir: "./content", trustedContent: true, gallery: { component: MyGallery } });
|
|
2165
|
+
* ```
|
|
2166
|
+
*/
|
|
2167
|
+
type GalleryOptions = {
|
|
2168
|
+
/**
|
|
2169
|
+
* Consumer Preact component rendering the gallery's inner content (SSR'd to
|
|
2170
|
+
* static markup at build). Receives {@link GalleryProps}. Defaults to the
|
|
2171
|
+
* built-in `GalleryTrack`.
|
|
2172
|
+
*/
|
|
2173
|
+
component?: GalleryComponent;
|
|
2174
|
+
};
|
|
2175
|
+
/**
|
|
2176
|
+
* Resolved gallery transform inputs — {@link GalleryOptions} plus the provider's
|
|
2177
|
+
* `contentDir` (needed to read the directive's `src` folder from disk). Assembled
|
|
2178
|
+
* by the pipeline wiring; not part of the public config surface.
|
|
2179
|
+
*/
|
|
2180
|
+
type GalleryTransformOptions = GalleryOptions & {
|
|
2181
|
+
/** The provider's content directory (folder reads resolve against it). */contentDir: string;
|
|
2182
|
+
};
|
|
2123
2183
|
/**
|
|
2124
2184
|
* Options for the node filesystem provider {@link ContentProvider} `fileSystemContent`.
|
|
2125
2185
|
* These are the markdown-pipeline + source concerns that used to live on the content
|
|
@@ -2164,6 +2224,17 @@ type FileSystemContentOptions = {
|
|
|
2164
2224
|
* (the facade is raw HTML the sanitize pass would strip). Defaults to disabled.
|
|
2165
2225
|
*/
|
|
2166
2226
|
embed?: boolean | EmbedOptions;
|
|
2227
|
+
/**
|
|
2228
|
+
* Folder galleries: rewrite `::gallery{src="./images/dir/" caption="…"}` leaf
|
|
2229
|
+
* directives into a swipeable image set. The framework reads the co-located
|
|
2230
|
+
* `src` folder, sorts its images, rewrites each to its shared `/<slug>/…` URL,
|
|
2231
|
+
* and renders them through a consumer Preact component (pair it with a gallery
|
|
2232
|
+
* SPA island for swipe/keyboard/lightbox). `true` enables with the default
|
|
2233
|
+
* component; an object passes {@link GalleryOptions} (e.g. a consumer
|
|
2234
|
+
* `component`). Requires `trustedContent: true` (the markup is raw HTML the
|
|
2235
|
+
* sanitize pass would strip). Defaults to disabled.
|
|
2236
|
+
*/
|
|
2237
|
+
gallery?: boolean | GalleryOptions;
|
|
2167
2238
|
};
|
|
2168
2239
|
/**
|
|
2169
2240
|
* Internal mutable state of the filesystem provider: the lazy unified processor and
|
package/dist/browser.mjs
CHANGED
|
@@ -3738,6 +3738,17 @@ async function performNavigation(pathname, handlers, signal) {
|
|
|
3738
3738
|
}
|
|
3739
3739
|
}
|
|
3740
3740
|
/**
|
|
3741
|
+
* Whether the user has asked the platform to minimise motion.
|
|
3742
|
+
*
|
|
3743
|
+
* @returns `true` when `(prefers-reduced-motion: reduce)` currently matches; `false` when
|
|
3744
|
+
* it does not, or when `matchMedia` is absent (guards SSR/test environments).
|
|
3745
|
+
* @example
|
|
3746
|
+
* const behavior: ScrollBehavior = prefersReducedMotion() ? "instant" : "smooth";
|
|
3747
|
+
*/
|
|
3748
|
+
function prefersReducedMotion() {
|
|
3749
|
+
return typeof globalThis.matchMedia === "function" && globalThis.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
3750
|
+
}
|
|
3751
|
+
/**
|
|
3741
3752
|
* Run a DOM-mutating swap, optionally wrapped in the View Transitions API when
|
|
3742
3753
|
* enabled and supported (instant swap otherwise — never throws).
|
|
3743
3754
|
*
|
|
@@ -3758,7 +3769,7 @@ async function performNavigation(pathname, handlers, signal) {
|
|
|
3758
3769
|
* runSwap(() => current.replaceWith(next), true, () => scrollTo({ top: 0, behavior: "instant" }));
|
|
3759
3770
|
*/
|
|
3760
3771
|
function runSwap(doSwap, viewTransitions, beforeCapture) {
|
|
3761
|
-
const reduced =
|
|
3772
|
+
const reduced = prefersReducedMotion();
|
|
3762
3773
|
const docWithVt = document;
|
|
3763
3774
|
const canUseViewTransitions = viewTransitions && !reduced && typeof docWithVt.startViewTransition === "function";
|
|
3764
3775
|
beforeCapture?.();
|
|
@@ -3856,7 +3867,7 @@ function attachHistoryFallback(handlers, navigate = (pathname, _scrollToTop, sig
|
|
|
3856
3867
|
if (pathWithSearch(url) === pathWithSearch(location)) {
|
|
3857
3868
|
window.scrollTo({
|
|
3858
3869
|
top: 0,
|
|
3859
|
-
behavior: "smooth"
|
|
3870
|
+
behavior: prefersReducedMotion() ? "instant" : "smooth"
|
|
3860
3871
|
});
|
|
3861
3872
|
return;
|
|
3862
3873
|
}
|
|
@@ -3910,7 +3921,7 @@ function attachNavigationApi(navigation, handlers, navigate = (pathname, _scroll
|
|
|
3910
3921
|
navEvent.intercept({ handler: () => {
|
|
3911
3922
|
window.scrollTo({
|
|
3912
3923
|
top: 0,
|
|
3913
|
-
behavior: "smooth"
|
|
3924
|
+
behavior: prefersReducedMotion() ? "instant" : "smooth"
|
|
3914
3925
|
});
|
|
3915
3926
|
return Promise.resolve();
|
|
3916
3927
|
} });
|
|
@@ -4087,26 +4098,30 @@ function createSpaKernel(state, config, emit, deps) {
|
|
|
4087
4098
|
let pendingScrollToTop = true;
|
|
4088
4099
|
/**
|
|
4089
4100
|
* Apply the in-flight navigation's scroll intent — the swap's `beforeCapture` hook.
|
|
4090
|
-
* For a forward nav it scrolls to top BEFORE the
|
|
4091
|
-
*
|
|
4092
|
-
* no
|
|
4093
|
-
*
|
|
4101
|
+
* For a forward nav it scrolls to top BEFORE the swap (and, with view transitions on,
|
|
4102
|
+
* before the "old" snapshot is captured), so the old and new states share scrollY=0:
|
|
4103
|
+
* no delta for a transition to animate → a `position: sticky` header never un-pins.
|
|
4104
|
+
* Traverse (back/forward) sets `pendingScrollToTop = false` and restores its saved
|
|
4105
|
+
* position after the swap instead.
|
|
4094
4106
|
*
|
|
4095
|
-
*
|
|
4096
|
-
*
|
|
4097
|
-
*
|
|
4098
|
-
*
|
|
4099
|
-
*
|
|
4107
|
+
* The reset is ALWAYS `"instant"`, never the CSS-driven `"auto"`. It runs synchronously
|
|
4108
|
+
* immediately before the swap, and the swap mutates document height (the outgoing page is
|
|
4109
|
+
* usually taller than the incoming one). A smooth scroll — from `behavior: "smooth"` or a
|
|
4110
|
+
* page `scroll-behavior: smooth` that `"auto"` would inherit — is still animating when that
|
|
4111
|
+
* height change lands; the browser clamps scrollY to the new, smaller maximum and cancels
|
|
4112
|
+
* the in-flight animation there (worst on WebKit), stranding the page near the OLD position
|
|
4113
|
+
* instead of the top. Instant lands scrollY=0 before the swap, every time. (A smooth
|
|
4114
|
+
* scroll-to-top on the SAME page is unaffected — the router's same-page handler animates
|
|
4115
|
+
* it, where there is no swap to race.)
|
|
4100
4116
|
*
|
|
4101
4117
|
* @example
|
|
4102
4118
|
* runSwap(renderAndMount, viewTransitions, applyPendingScroll);
|
|
4103
4119
|
*/
|
|
4104
4120
|
const applyPendingScroll = () => {
|
|
4105
4121
|
if (!pendingScrollToTop) return;
|
|
4106
|
-
const behavior = resolved.viewTransitions ? "instant" : "auto";
|
|
4107
4122
|
window.scrollTo({
|
|
4108
4123
|
top: 0,
|
|
4109
|
-
behavior
|
|
4124
|
+
behavior: "instant"
|
|
4110
4125
|
});
|
|
4111
4126
|
};
|
|
4112
4127
|
/**
|