narraleaf-react 0.25.0 → 0.27.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/game/nlcore/action/actionHistory.d.ts +8 -0
- package/dist/game/nlcore/action/actionTypes.d.ts +1 -1
- package/dist/game/nlcore/action/actions/sceneAction.d.ts +9 -2
- package/dist/game/nlcore/action/baseElement.d.ts +14 -0
- package/dist/game/nlcore/action/gameHistory.d.ts +55 -8
- package/dist/game/nlcore/common/elements.d.ts +1 -0
- package/dist/game/nlcore/elements/camera.d.ts +13 -2
- package/dist/game/nlcore/elements/character/word.d.ts +96 -0
- package/dist/game/nlcore/elements/character.d.ts +10 -3
- package/dist/game/nlcore/elements/scene.d.ts +13 -1
- package/dist/game/nlcore/elements/transition/transitions/image/imageTransition.d.ts +14 -0
- package/dist/game/nlcore/game/liveGame.d.ts +48 -17
- package/dist/game/nlcore/gameTypes.d.ts +19 -4
- package/dist/game/player/elements/say/Sentence.d.ts +24 -1
- package/dist/game/player/elements/say/dialogOverlay.d.ts +52 -0
- package/dist/game/player/elements/say/wordRenderer.d.ts +29 -0
- package/dist/game/player/elements/scene/stageTransition.d.ts +47 -0
- package/dist/game/player/gameState.d.ts +31 -0
- package/dist/game/player/lib/elementProps.d.ts +1 -0
- package/dist/game/player/lib/useSuspendAdvance.d.ts +22 -0
- package/dist/game/player/lib/verticalText.d.ts +58 -0
- package/dist/game/player/libElements.d.ts +13 -1
- package/dist/main.js +52 -50
- package/package.json +1 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { WordRenderProps } from "../../../nlcore/elements/character/word";
|
|
2
|
+
import type React from "react";
|
|
3
|
+
/**
|
|
4
|
+
* Register a component that words may name by id.
|
|
5
|
+
*
|
|
6
|
+
* Registering the same id again replaces the component; lines already on screen pick the new one up
|
|
7
|
+
* on their next render.
|
|
8
|
+
*
|
|
9
|
+
* @param id - The id words refer to, e.g. `"glossary"`.
|
|
10
|
+
* @param component - The component to render those words with.
|
|
11
|
+
* @returns A function that unregisters it again.
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* registerWordRenderer("glossary", GlossaryTerm);
|
|
15
|
+
* // a word compiled from story data can now ask for it by name
|
|
16
|
+
* new Word("以太浓度", {render: "glossary", data: {entry: "aether"}});
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare function registerWordRenderer<T = unknown>(id: string, component: React.ComponentType<WordRenderProps<T>>): () => void;
|
|
20
|
+
/**
|
|
21
|
+
* Drop a registration made by {@link registerWordRenderer}.
|
|
22
|
+
* @param id - The id to forget.
|
|
23
|
+
*/
|
|
24
|
+
export declare function unregisterWordRenderer(id: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* The component registered under an id, or `null`.
|
|
27
|
+
* @param id - The id to look up.
|
|
28
|
+
*/
|
|
29
|
+
export declare function getWordRenderer(id: string): React.ComponentType<WordRenderProps<any>> | null;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Scene } from "../../../nlcore/elements/scene";
|
|
2
|
+
import type { CSSProps } from "../../../nlcore/elements/transition/type";
|
|
3
|
+
/**
|
|
4
|
+
* Which scene each half of a stage transition drives.
|
|
5
|
+
*
|
|
6
|
+
* A transition task's resolvers are already split by {@link Transition.asPrev} / {@link
|
|
7
|
+
* Transition.asTarget}; this is what those two roles mean at the stage level.
|
|
8
|
+
*/
|
|
9
|
+
export type StageTransitionRoles = {
|
|
10
|
+
/** The scene being left. Driven by the `asPrev` resolvers. */
|
|
11
|
+
from: Scene;
|
|
12
|
+
/** The scene being entered. Driven by the `asTarget` resolvers. */
|
|
13
|
+
to: Scene;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* What a scene root paints when no transition owns it.
|
|
17
|
+
*
|
|
18
|
+
* This must name **every** property any transition writes to a scene half. A property left out
|
|
19
|
+
* is not neutral — it keeps whatever the last frame put there. That is survivable for the
|
|
20
|
+
* outgoing scene (it is unmounted moments later) but not for the incoming one, which lives on:
|
|
21
|
+
* a `Reveal` leaves a fully-opaque `mask-image` behind, and the scene would then carry that mask
|
|
22
|
+
* for the rest of its life. Cancellation is worse still — it stops mid-flight with no final
|
|
23
|
+
* frame, so a half-way value would stick forever on both halves.
|
|
24
|
+
*
|
|
25
|
+
* `stageSettledStyle.test.ts` pins this list against what the built-in transitions actually
|
|
26
|
+
* write, so a transition cannot start writing a property without this naming it.
|
|
27
|
+
*/
|
|
28
|
+
export declare function stageSettledStyle(): CSSProps;
|
|
29
|
+
/**
|
|
30
|
+
* What the scene a transition moved away from paints once the transition is over: nothing.
|
|
31
|
+
*
|
|
32
|
+
* The transition finishing is not what removes the outgoing scene — `scene:exit` is a separate
|
|
33
|
+
* action, so the scene stays mounted for a moment afterwards, and during that moment it must not be
|
|
34
|
+
* on screen. Leaving that to the stacking order does not work: settling gives the incoming scene
|
|
35
|
+
* `z-index: auto` while the outgoing one still carries an explicit `0`, and those are the same
|
|
36
|
+
* stacking level, so document order decides — and the outgoing scene is the later node. It comes to
|
|
37
|
+
* the front, at whatever opacity its half of the transition left it at.
|
|
38
|
+
*
|
|
39
|
+
* A `Dissolve` hides that, because its outgoing half ends at zero opacity. A `Reveal` does not: its
|
|
40
|
+
* outgoing half is `{}`, never touched at all, because the effect is entirely the incoming scene
|
|
41
|
+
* being uncovered on top of it. So the scene the player just left reappears, at full opacity, in
|
|
42
|
+
* front — for as many frames as `scene:exit` takes to arrive.
|
|
43
|
+
*
|
|
44
|
+
* Hiding it is also what the per-element path has always done: `useDisplayable` discards the
|
|
45
|
+
* element that played the outgoing half the moment the transition completes.
|
|
46
|
+
*/
|
|
47
|
+
export declare function stageRetiredStyle(): CSSProps;
|
|
@@ -193,6 +193,7 @@ export declare class GameState {
|
|
|
193
193
|
readonly gameHistory: GameHistoryManager;
|
|
194
194
|
pageRouter: null;
|
|
195
195
|
private stageClickBuffer;
|
|
196
|
+
private readonly advanceSuspensions;
|
|
196
197
|
private readonly nvlAdvanceWaiters;
|
|
197
198
|
private advDialogState;
|
|
198
199
|
private _fastForwarding;
|
|
@@ -318,6 +319,24 @@ export declare class GameState {
|
|
|
318
319
|
settleAdvDialog(dialogId: string): this;
|
|
319
320
|
getAdvDialogState(): AdvDialogState | null;
|
|
320
321
|
recordStageClick(): this;
|
|
322
|
+
/**
|
|
323
|
+
* Hold the line where it is: while at least one suspension is out, clicking the stage and
|
|
324
|
+
* pressing the advance or skip key do nothing.
|
|
325
|
+
*
|
|
326
|
+
* Anything that opens on top of a line and wants the player's next keystroke needs this — a
|
|
327
|
+
* definition popup on an inline word, a term the player is reading. Without it a popup opens and
|
|
328
|
+
* the very next space bar advances the line behind it, which is the one thing the popup exists
|
|
329
|
+
* to prevent.
|
|
330
|
+
*
|
|
331
|
+
* Suspensions nest: the line resumes once every one of them has been released.
|
|
332
|
+
*
|
|
333
|
+
* @returns A function that releases this suspension. Safe to call more than once.
|
|
334
|
+
*/
|
|
335
|
+
suspendAdvance(): () => void;
|
|
336
|
+
/**
|
|
337
|
+
* Whether anything is currently holding the line — see {@link GameState.suspendAdvance}.
|
|
338
|
+
*/
|
|
339
|
+
isAdvanceSuspended(): boolean;
|
|
321
340
|
consumeStageClick(maxAgeMs?: number): boolean;
|
|
322
341
|
createDisplayable(displayable: LogicAction.DisplayableElements, scene?: Scene | null, layer?: Layer | null): this;
|
|
323
342
|
disposeDisplayable(displayable: LogicAction.DisplayableElements, scene?: Scene | null, layer?: Layer | null): this;
|
|
@@ -366,6 +385,18 @@ export declare class GameState {
|
|
|
366
385
|
createElementSnapshot(element: PlayerStateElement): PlayerStateElementSnapshot;
|
|
367
386
|
fromElementSnapshot(snapshot: PlayerStateElementSnapshot): PlayerStateElement;
|
|
368
387
|
private removeElements;
|
|
388
|
+
/**
|
|
389
|
+
* Leaving a scene returns everything the scene put on stage to the pose its constructor config
|
|
390
|
+
* describes — the displayables on each layer, and the layers themselves, which are mutable at
|
|
391
|
+
* runtime and would otherwise carry a slide or a fade into the next scene.
|
|
392
|
+
*
|
|
393
|
+
* The story camera is the one displayable that deliberately outlives a scene (a story owns
|
|
394
|
+
* exactly one, and it frames the whole stage across scene changes), so it is skipped here.
|
|
395
|
+
* Nothing in the engine's own pipeline can put it on a layer — only images, texts and puppets
|
|
396
|
+
* emit `displayable:init`, which is what registers an element into the layer map — but a host
|
|
397
|
+
* may register any displayable by hand through `DevTools.registerDisplayable`, so the camera is
|
|
398
|
+
* excluded explicitly rather than by trusting that route to stay closed.
|
|
399
|
+
*/
|
|
369
400
|
private resetLayers;
|
|
370
401
|
private syncNvlDerivedState;
|
|
371
402
|
private emitNvlStateChange;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hold the line while something of yours is open.
|
|
3
|
+
*
|
|
4
|
+
* A popup drawn over a line — a definition of an inline word, a term the player is reading — has to
|
|
5
|
+
* stop the line advancing underneath it, or the space bar that should dismiss the popup skips to
|
|
6
|
+
* the next line instead. Pass `true` while it is open and the stage click, the advance key and the
|
|
7
|
+
* skip key all stop reaching the dialog; the hold is released on `false`, and on unmount, so a
|
|
8
|
+
* popup that disappears can never leave the game stuck.
|
|
9
|
+
*
|
|
10
|
+
* Several holds may be out at once; the line resumes when the last one is released.
|
|
11
|
+
*
|
|
12
|
+
* @param active - Whether to hold the line right now.
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* function GlossaryTerm({children, revealed, data}: WordRenderProps<{entry: string}>) {
|
|
16
|
+
* const [open, setOpen] = useState(false);
|
|
17
|
+
* useSuspendAdvance(open);
|
|
18
|
+
* return <span onClick={() => revealed && setOpen(v => !v)}>{children}</span>;
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare function useSuspendAdvance(active: boolean): void;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vertical typesetting helpers shared by the typewriter and the preview renderer.
|
|
3
|
+
*
|
|
4
|
+
* A vertical box is set the way a Japanese novel is: glyphs stand upright in a column that reads
|
|
5
|
+
* top to bottom, and the next column starts to the left. Two things in that layout are not free,
|
|
6
|
+
* and both are about text that is not Japanese:
|
|
7
|
+
*
|
|
8
|
+
* - A Latin word must stay whole. `word-break: break-all`, which the horizontal renderer wants so
|
|
9
|
+
* that CJK wraps anywhere, will otherwise split "Prologue" across two columns, one glyph at a
|
|
10
|
+
* time, sideways.
|
|
11
|
+
* - A short run - a two-digit number, an initialism - reads better set upright across the column
|
|
12
|
+
* than laid on its side. That is tate-chu-yoko (縦中横), and CSS spells it
|
|
13
|
+
* `text-combine-upright: all` on a wrapper around exactly that run.
|
|
14
|
+
*/
|
|
15
|
+
import React from "react";
|
|
16
|
+
export type TextWritingMode = "horizontal-tb" | "vertical-rl" | "vertical-lr";
|
|
17
|
+
export type TextGlyphOrientation = "mixed" | "upright" | "sideways";
|
|
18
|
+
/**
|
|
19
|
+
* Tate-chu-yoko setting: `true` uses the typographic default of two characters, a number sets the
|
|
20
|
+
* longest run to combine, and `false` turns it off.
|
|
21
|
+
*/
|
|
22
|
+
export type TateChuYoko = boolean | number;
|
|
23
|
+
export declare const DEFAULT_TATE_CHU_YOKO_MAX_LENGTH = 2;
|
|
24
|
+
export declare function isVerticalWritingMode(mode: TextWritingMode | undefined): boolean;
|
|
25
|
+
/** The longest run to combine, or 0 when tate-chu-yoko is off. */
|
|
26
|
+
export declare function resolveTateChuYokoMaxLength(setting: TateChuYoko | undefined): number;
|
|
27
|
+
/**
|
|
28
|
+
* The writing-mode half of the text container's style.
|
|
29
|
+
*
|
|
30
|
+
* `text-orientation` is only written while vertical, where it means something; in a horizontal box
|
|
31
|
+
* it would sit in the inline style doing nothing.
|
|
32
|
+
*/
|
|
33
|
+
export declare function verticalContainerStyle(mode: TextWritingMode | undefined, orientation: TextGlyphOrientation | undefined): React.CSSProperties;
|
|
34
|
+
export type VerticalTextSegment = {
|
|
35
|
+
text: string;
|
|
36
|
+
combineUpright: boolean;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Splits text into the runs tate-chu-yoko combines and the text around them.
|
|
40
|
+
*
|
|
41
|
+
* A run longer than `maxLength` is left in the surrounding segment rather than cut down to fit:
|
|
42
|
+
* a long English word belongs on its side, which is what the writing mode does with it anyway.
|
|
43
|
+
*/
|
|
44
|
+
export declare function segmentVerticalText(text: string, maxLength: number): VerticalTextSegment[];
|
|
45
|
+
/**
|
|
46
|
+
* How a word's own box breaks.
|
|
47
|
+
*
|
|
48
|
+
* Vertical text keeps `word-break: normal`, which still breaks between CJK characters - that rule
|
|
49
|
+
* has never needed `break-all` - while leaving Latin words whole.
|
|
50
|
+
*/
|
|
51
|
+
export declare function wordBreakStyleFor(vertical: boolean): React.CSSProperties;
|
|
52
|
+
/**
|
|
53
|
+
* Renders a word's text with its short runs set upright.
|
|
54
|
+
*
|
|
55
|
+
* Returns the string itself when nothing would be combined, so horizontal text - and vertical text
|
|
56
|
+
* with no Latin in it - is one text node, exactly as before.
|
|
57
|
+
*/
|
|
58
|
+
export declare function renderWordText(text: string, vertical: boolean, tateChuYoko: TateChuYoko | undefined): React.ReactNode;
|
|
@@ -21,9 +21,21 @@ import { NvlContainer } from "./elements/nvl/NvlContainer";
|
|
|
21
21
|
import { DefaultNvlContainer } from "./elements/nvl/DefaultNvlContainer";
|
|
22
22
|
import { NvlDialogList, DefaultNvlDialogItem } from "./elements/nvl/NvlDialogList";
|
|
23
23
|
import { NvlProvider, useNvl, useNvlDialogs, useIsNvlMode, useIsNvlVisible } from "./elements/nvl/NvlContext";
|
|
24
|
+
import { getWordRenderer, registerWordRenderer, unregisterWordRenderer } from "./elements/say/wordRenderer";
|
|
25
|
+
import { useDialogOverlay } from "./elements/say/dialogOverlay";
|
|
26
|
+
import { useSuspendAdvance } from "./lib/useSuspendAdvance";
|
|
24
27
|
export type { DialogAvatarContext } from "./elements/say/Avatar";
|
|
25
28
|
export type { BaseTextsProps, EntryTextsProps, RawTextsProps, TextAppearanceProps, TextsPreviewInput, TextsPreviewLoop, TextsPreviewProps, TextsProps, } from "./elements/say/Sentence";
|
|
29
|
+
/**
|
|
30
|
+
* The vocabulary of the vertical-text props on `TextAppearanceProps`.
|
|
31
|
+
*
|
|
32
|
+
* Exported because a value has to be named somewhere other than the JSX attribute: an application
|
|
33
|
+
* that keeps its typography in a settings object, or hands the mode down through its own props,
|
|
34
|
+
* had no way to type either without restating the unions.
|
|
35
|
+
*/
|
|
36
|
+
export type { TateChuYoko, TextGlyphOrientation, TextWritingMode, } from "./lib/verticalText";
|
|
37
|
+
export type { DialogOverlay, DialogOverlayRect } from "./elements/say/dialogOverlay";
|
|
26
38
|
export type { NametagProps } from "./elements/say/Nametag";
|
|
27
39
|
export type { ItemProps } from "./elements/menu/UIMenu/Item";
|
|
28
40
|
export type { ChoiceEvaluated } from "./elements/menu/type";
|
|
29
|
-
export { Isolated, usePreference, Stage, GameMenu, Item, useUIMenuContext, Notifications, Texts, TextsPreview, Nametag, Dialog, Avatar, useAvatar, useDialog, useVoiceState, Page, Layout, LayoutRouterProvider, PageInjectContext, RootPath, FixedAspectRatioContainer, useKeyBinding, useLiveGame, NvlContainer, DefaultNvlContainer, NvlDialogList, DefaultNvlDialogItem, NvlProvider, useNvl, useNvlDialogs, useIsNvlMode, useIsNvlVisible, };
|
|
41
|
+
export { Isolated, usePreference, Stage, GameMenu, Item, useUIMenuContext, Notifications, Texts, TextsPreview, Nametag, Dialog, Avatar, useAvatar, useDialog, useDialogOverlay, useSuspendAdvance, registerWordRenderer, unregisterWordRenderer, getWordRenderer, useVoiceState, Page, Layout, LayoutRouterProvider, PageInjectContext, RootPath, FixedAspectRatioContainer, useKeyBinding, useLiveGame, NvlContainer, DefaultNvlContainer, NvlDialogList, DefaultNvlDialogItem, NvlProvider, useNvl, useNvlDialogs, useIsNvlMode, useIsNvlVisible, };
|