narraleaf-react 0.9.0 → 0.10.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.
Files changed (46) hide show
  1. package/LICENSE +373 -373
  2. package/README.md +165 -147
  3. package/dist/built-in.d.ts +3 -0
  4. package/dist/built-in.js +1 -0
  5. package/dist/game/nlcore/action/action.d.ts +9 -5
  6. package/dist/game/nlcore/action/actionTypes.d.ts +10 -10
  7. package/dist/game/nlcore/action/actions/menuAction.d.ts +1 -4
  8. package/dist/game/nlcore/action/logicAction.d.ts +29 -29
  9. package/dist/game/nlcore/common/elements.d.ts +4 -2
  10. package/dist/game/nlcore/common/transition.d.ts +2 -1
  11. package/dist/game/nlcore/elements/built-in/DevTools.d.ts +2 -0
  12. package/dist/game/nlcore/elements/built-in/built-in.d.ts +2 -0
  13. package/dist/game/nlcore/elements/built-in/screenEffects.d.ts +31 -0
  14. package/dist/game/nlcore/elements/character/avatar.d.ts +35 -0
  15. package/dist/game/nlcore/elements/character/sentence.d.ts +14 -0
  16. package/dist/game/nlcore/elements/character.d.ts +30 -0
  17. package/dist/game/nlcore/elements/displayable/displayable.d.ts +84 -0
  18. package/dist/game/nlcore/elements/displayable/image.d.ts +2 -2
  19. package/dist/game/nlcore/elements/displayable/text.d.ts +2 -2
  20. package/dist/game/nlcore/elements/layer.d.ts +1 -2
  21. package/dist/game/nlcore/elements/scene.d.ts +2 -1
  22. package/dist/game/nlcore/elements/transform/transform.d.ts +26 -3
  23. package/dist/game/nlcore/elements/transform/type.d.ts +30 -2
  24. package/dist/game/nlcore/elements/transition/transitions/image/maskTransition.d.ts +38 -0
  25. package/dist/game/nlcore/game.d.ts +60 -0
  26. package/dist/game/nlcore/gameTypes.d.ts +1 -36
  27. package/dist/game/player/Tasks.d.ts +4 -1
  28. package/dist/game/player/elements/Player.d.ts +1 -1
  29. package/dist/game/player/elements/menu/UIMenu/Item.d.ts +3 -2
  30. package/dist/game/player/elements/menu/type.d.ts +1 -0
  31. package/dist/game/player/elements/say/Avatar.d.ts +13 -0
  32. package/dist/game/player/elements/say/Nametag.d.ts +6 -3
  33. package/dist/game/player/elements/say/Sentence.d.ts +76 -13
  34. package/dist/game/player/elements/say/UIDialog.d.ts +6 -2
  35. package/dist/game/player/elements/say/type.d.ts +4 -2
  36. package/dist/game/player/elements/say/useDialog.d.ts +3 -0
  37. package/dist/game/player/elements/type.d.ts +27 -2
  38. package/dist/game/player/gameState.d.ts +5 -0
  39. package/dist/game/player/lib/AudioManager.d.ts +1 -0
  40. package/dist/game/player/lib/ErrorFallback.d.ts +5 -1
  41. package/dist/game/player/lib/Preloaded.d.ts +1 -0
  42. package/dist/game/player/libElements.d.ts +7 -2
  43. package/dist/game/player/provider/game-state.d.ts +1 -0
  44. package/dist/main.js +42 -40
  45. package/dist/util/data.d.ts +15 -2
  46. package/package.json +114 -107
@@ -1,33 +1,93 @@
1
1
  import { Pausing } from "../../../nlcore/elements/character/pause";
2
- import { Sentence } from "../../../nlcore/elements/character/sentence";
2
+ import { Sentence, type StaticWord } from "../../../nlcore/elements/character/sentence";
3
3
  import { Word } from "../../../nlcore/elements/character/word";
4
4
  import { GameState } from "../../../../game/nlcore/common/game";
5
5
  import { Color } from "../../../../game/nlcore/types";
6
6
  import React from "react";
7
- import { DialogElementProps } from "./type";
8
7
  import { DialogState } from "./UIDialog";
9
8
  import type { NvlDialogEntry } from "../../gameState";
10
- type BaseTextsProps = {
9
+ export type TextAppearanceProps = {
11
10
  /**
12
11
  * The default color of the text
13
12
  */
14
13
  defaultColor?: Color;
14
+ fontSize?: React.CSSProperties["fontSize"];
15
+ fontWeight?: React.CSSProperties["fontWeight"];
16
+ fontWeightBold?: React.CSSProperties["fontWeight"];
17
+ fontFamily?: React.CSSProperties["fontFamily"];
18
+ };
19
+ export type BaseTextsProps = TextAppearanceProps & {
15
20
  className?: string;
16
21
  style?: React.CSSProperties;
17
22
  dialog?: DialogState;
18
23
  } & React.HTMLAttributes<HTMLDivElement>;
19
- /**
20
- * Props-based wrapper component
21
- * Provides a clean interface for direct prop usage
22
- */
23
- export interface TextsProps extends DialogElementProps {
24
- sentence: Sentence;
25
- gameState: GameState;
24
+ export type TextsPreviewInput = StaticWord<string | Pausing> | StaticWord<string | Pausing>[];
25
+ export type TextsPreviewLoop = boolean | {
26
+ /**
27
+ * Whether the preview restarts after the current type effect completes.
28
+ * @default true
29
+ */
30
+ enabled?: boolean;
31
+ /**
32
+ * Delay before the next preview cycle starts, in milliseconds.
33
+ * @default 1000
34
+ */
35
+ delay?: number;
36
+ };
37
+ export interface TextsPreviewProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
38
+ /**
39
+ * Static text or words to preview.
40
+ */
41
+ text?: TextsPreviewInput;
42
+ /**
43
+ * Sentence to preview. Dynamic words are not evaluated; pass `words` when
44
+ * previewing already-evaluated runtime content.
45
+ */
46
+ sentence?: Sentence;
47
+ /**
48
+ * Already-evaluated words, useful when previewing dynamic sentence content.
49
+ */
50
+ words?: Word<Pausing | string>[];
51
+ /**
52
+ * Whether the preview should use the rolling type effect.
53
+ * @default true
54
+ */
26
55
  useTypeEffect?: boolean;
56
+ /**
57
+ * Loop behavior for settings screens and other static previews.
58
+ * @default true
59
+ */
60
+ loop?: TextsPreviewLoop;
61
+ /**
62
+ * Delay before replay when `loop` is `true`, in milliseconds.
63
+ * Ignored when `loop` is an object with `delay`.
64
+ * @default 1000
65
+ */
66
+ restartDelay?: number;
67
+ /**
68
+ * Characters per second used by the preview.
69
+ * @default current game's `cps` preference, or Game.DefaultPreference.cps outside GameProvider
70
+ */
71
+ cps?: number;
72
+ /**
73
+ * Speed multiplier used by the preview.
74
+ * @default current game's `gameSpeed` preference, or Game.DefaultPreference.gameSpeed outside GameProvider
75
+ */
76
+ gameSpeed?: number;
77
+ /**
78
+ * Duration for a pause without an explicit duration, in milliseconds.
79
+ * @default current game's `autoForwardDefaultPause` config, or Game.DefaultConfig.autoForwardDefaultPause outside GameProvider
80
+ */
81
+ pauseDuration?: number;
82
+ /**
83
+ * Fallback color when neither the word nor the sentence defines one.
84
+ */
85
+ defaultColor?: Color;
86
+ fontSize?: React.CSSProperties["fontSize"];
87
+ fontWeight?: React.CSSProperties["fontWeight"];
88
+ fontWeightBold?: React.CSSProperties["fontWeight"];
89
+ fontFamily?: React.CSSProperties["fontFamily"];
27
90
  onCompleted?: () => void;
28
- finished?: boolean;
29
- count?: number;
30
- words?: Word<Pausing | string>[];
31
91
  }
32
92
  export type EntryTextsProps = BaseTextsProps & {
33
93
  entry: NvlDialogEntry;
@@ -36,10 +96,13 @@ export type EntryTextsProps = BaseTextsProps & {
36
96
  useTypeEffect: boolean;
37
97
  isActive: boolean;
38
98
  };
99
+ export declare function TextsPreview({ text, sentence, words, useTypeEffect, loop, restartDelay, cps, gameSpeed, pauseDuration, defaultColor, className, style, fontSize, fontWeight, fontWeightBold, fontFamily, onCompleted, ...props }: TextsPreviewProps): React.JSX.Element;
100
+ export type RawTextsProps = BaseTextsProps;
39
101
  export declare function RawTexts(props: BaseTextsProps): React.JSX.Element;
40
102
  /**
41
103
  * Context-based wrapper component
42
104
  * Provides integration with the sentence context
43
105
  */
106
+ export type TextsProps = BaseTextsProps | EntryTextsProps;
44
107
  export declare function Texts(props: BaseTextsProps | EntryTextsProps): React.JSX.Element;
45
108
  export default Texts;
@@ -6,7 +6,7 @@ import React from "react";
6
6
  import { DialogAction, DialogStateType, SayElementProps } from "./type";
7
7
  type DialogEvents = {
8
8
  "event:dialog.requestComplete": [];
9
- "event:dialog.complete": [force: boolean];
9
+ "event:dialog.complete": [force?: boolean];
10
10
  "event:dialog.forceSkip": [];
11
11
  "event:dialog.onFlush": [];
12
12
  "event:dialog.simulateClick": [];
@@ -16,6 +16,7 @@ type DialogStateConfig = {
16
16
  action: DialogAction;
17
17
  evaluatedWords: Word<Pausing | string>[];
18
18
  gameState: GameState;
19
+ suppressInitialAnimation?: boolean;
19
20
  };
20
21
  export declare class DialogState {
21
22
  static Events: {
@@ -31,12 +32,15 @@ export declare class DialogState {
31
32
  private _count;
32
33
  private _forceSkipped;
33
34
  private _idle;
35
+ private _active;
34
36
  private autoForwardScheduler;
35
37
  constructor(config: DialogStateConfig);
36
38
  get state(): DialogStateType;
37
39
  get deps(): React.DependencyList;
38
40
  isIdle(): boolean;
39
41
  setIdle(idle: boolean): void;
42
+ isActive(): boolean;
43
+ setActive(active: boolean): this;
40
44
  /**
41
45
  * Only for dialog component to call
42
46
  *
@@ -68,5 +72,5 @@ export declare class DialogState {
68
72
  safeEmit(event: keyof DialogEvents, ...args: DialogEvents[keyof DialogEvents]): this;
69
73
  private scheduleAutoForward;
70
74
  }
71
- export default function PlayerDialog({ action, onFinished, useTypeEffect, gameState, }: Readonly<SayElementProps>): React.JSX.Element;
75
+ export default function PlayerDialog({ action, onFinished, useTypeEffect, gameState, active, }: Readonly<SayElementProps>): React.JSX.Element;
72
76
  export {};
@@ -4,6 +4,7 @@ import { Sentence } from "../../../nlcore/elements/character/sentence";
4
4
  import { Word } from "../../../nlcore/elements/character/word";
5
5
  import { Pausing } from "../../../nlcore/elements/character/pause";
6
6
  import React from "react";
7
+ import type { HTMLMotionProps } from "motion/react";
7
8
  export interface SayElementProps {
8
9
  action: {
9
10
  sentence: Sentence | null;
@@ -19,12 +20,13 @@ export interface SayElementProps {
19
20
  onFinished?: (skiped?: boolean) => void;
20
21
  useTypeEffect?: boolean;
21
22
  gameState: GameState;
23
+ active?: boolean;
22
24
  }
23
25
  export interface IDialogProps {
24
26
  }
25
27
  export type DialogProps = {
26
- children: React.ReactNode;
27
- } & React.HTMLAttributes<HTMLDivElement>;
28
+ children?: React.ReactNode;
29
+ } & HTMLMotionProps<"div">;
28
30
  export type DialogElementProps = {
29
31
  children?: never;
30
32
  } & React.HTMLAttributes<HTMLDivElement>;
@@ -1,3 +1,4 @@
1
+ import type { SentenceMetadata } from "../../../nlcore/elements/character/sentence";
1
2
  /**
2
3
  * Represents the context of a dialog, containing information about its completion status
3
4
  * and the text content.
@@ -9,6 +10,8 @@ export type DialogContext = {
9
10
  text: string;
10
11
  /** Whether the dialog is the narrator */
11
12
  isNarrator: boolean;
13
+ /** User-provided runtime metadata from the current sentence, if any */
14
+ metadata?: SentenceMetadata;
12
15
  };
13
16
  /**
14
17
  * A custom hook that provides access to the current dialog's state and content.
@@ -3,7 +3,7 @@ import { IDialogProps, SayElementProps } from "../elements/say/type";
3
3
  import { IUserMenuProps, MenuElementProps } from "../elements/menu/type";
4
4
  import { Story } from "../../nlcore/elements/story";
5
5
  import clsx from "clsx";
6
- import { Game } from "../../nlcore/game";
6
+ import { Game, type GameLifecycleEventContext } from "../../nlcore/game";
7
7
  import { GameState } from "../gameState";
8
8
  import { Storable } from "../../nlcore/elements/persistent/storable";
9
9
  import { LiveGame } from "../../nlcore/game/liveGame";
@@ -28,17 +28,42 @@ export type PlayerEventContext = {
28
28
  liveGame: LiveGame;
29
29
  storable: Storable;
30
30
  };
31
+ export type PlayerLifecycleEventContext = GameLifecycleEventContext;
31
32
  export interface PlayerProps {
32
33
  story?: Story;
33
34
  width?: string | number;
34
35
  height?: string | number;
35
36
  className?: clsx.ClassValue;
36
37
  /**
37
- * Once the game is ready to be played
38
+ * Once the Player is initialized.
39
+ *
40
+ * This is not a preload or first-render guarantee. Use
41
+ * {@link PlayerProps.onPreloadComplete} or {@link PlayerProps.onFirstSceneReady}
42
+ * when you need those exact lifecycle points.
38
43
  *
39
44
  * only called each lifecycle once
40
45
  */
41
46
  onReady?: (ctx: PlayerEventContext) => void;
47
+ /**
48
+ * Once the initial preload pass has actually completed.
49
+ *
50
+ * This fires before the first scene is guaranteed to be rendered.
51
+ */
52
+ onPreloadComplete?: (ctx: PlayerLifecycleEventContext) => void;
53
+ /**
54
+ * Once the internal preload pass is ready and the Player has committed that state.
55
+ *
56
+ * only called each lifecycle once
57
+ *
58
+ * @deprecated Use {@link PlayerProps.onPreloadComplete}.
59
+ */
60
+ onPreloadedReady?: (ctx: PlayerEventContext) => void;
61
+ /**
62
+ * Once the first scene has mounted and the browser has had a frame to render it.
63
+ *
64
+ * This is the most direct signal that the game is visually ready for the player.
65
+ */
66
+ onFirstSceneReady?: (ctx: PlayerLifecycleEventContext) => void;
42
67
  /**
43
68
  * Once the game is ended
44
69
  *
@@ -28,6 +28,7 @@ import { GameHistoryManager } from "../../game/nlcore/action/gameHistory";
28
28
  import type { Character } from "../nlcore/elements/character";
29
29
  import type { TransformDefinitions } from "../nlcore/elements/transform/type";
30
30
  import type { NvlBlockOptions } from "../nlcore/action/actionTypes";
31
+ import { type NormalizedCharacterPortraitConfig } from "../nlcore/elements/character/avatar";
31
32
  export type NvlDialogEntry = {
32
33
  id: string;
33
34
  actionId: string;
@@ -119,6 +120,8 @@ type GameStateEvents = {
119
120
  "event:state.player.lineEnd": [];
120
121
  "event:state.player.requestFlush": [];
121
122
  "event:state.player.stageClick": [];
123
+ "event:state.scene.mount": [scene: Scene];
124
+ "event:state.scene.unmount": [scene: Scene];
122
125
  "event.state.onExpose": [unknown, ExposedState[ExposedStateType]];
123
126
  "event:state.onRender": [];
124
127
  "event:state:flushPreloadedScenes": [];
@@ -182,6 +185,7 @@ export declare class GameState {
182
185
  getSceneElements(): PlayerStateElement[];
183
186
  getLastScene(): Scene | null;
184
187
  getCurrentScene(): Scene | null;
188
+ findCurrentPortraitForCharacter(character: Character): NormalizedCharacterPortraitConfig | null;
185
189
  sceneExists(scene?: Scene): boolean;
186
190
  isSceneActive(scene: Scene): boolean;
187
191
  wait(ms: number): Promise<void>;
@@ -317,6 +321,7 @@ export declare class GameState {
317
321
  private syncNvlDerivedState;
318
322
  private emitNvlStateChange;
319
323
  private resolveNvlAdvance;
324
+ private isDisplayableVisible;
320
325
  private createWaitableAction;
321
326
  private sceneNotFound;
322
327
  private layerNotFound;
@@ -21,6 +21,7 @@ export declare class AudioManager {
21
21
  private sound;
22
22
  private ready;
23
23
  private isReady;
24
+ private isInitializing;
24
25
  constructor(gameState: GameState);
25
26
  /**
26
27
  * Must be called ONCE on the client side to prepare audio subsystem.
@@ -1,5 +1,9 @@
1
1
  import React, { ErrorInfo } from "react";
2
+ type ErrorFallbackInfo = ErrorInfo & {
3
+ digest?: string;
4
+ };
2
5
  export default function ErrorFallback({ error, errorInfo }: {
3
6
  error: Error;
4
- errorInfo: ErrorInfo;
7
+ errorInfo: ErrorFallbackInfo;
5
8
  }): React.JSX.Element;
9
+ export {};
@@ -27,6 +27,7 @@ export type PreloadedEventTypes = {
27
27
  "event:preloaded.change": [];
28
28
  "event:preloaded.mount": [];
29
29
  "event:preloaded.ready": [];
30
+ "event:preloaded.complete": [];
30
31
  "event:preloaded.unmount": [];
31
32
  };
32
33
  export declare class Preloaded {
@@ -4,9 +4,10 @@ import { Stage } from "./lib/PageRouter/Stage";
4
4
  import GameMenu from "./elements/menu/UIMenu/Menu";
5
5
  import Item from "./elements/menu/UIMenu/Item";
6
6
  import Notifications from "./elements/notification/Notifications";
7
- import Texts from "./elements/say/Sentence";
7
+ import Texts, { TextsPreview } from "./elements/say/Sentence";
8
8
  import Nametag from "./elements/say/Nametag";
9
9
  import Dialog from "./elements/say/Dialog";
10
+ import Avatar, { useAvatar } from "./elements/say/Avatar";
10
11
  import { useDialog } from "./elements/say/useDialog";
11
12
  import { useVoiceState } from "./elements/say/useVoiceState";
12
13
  import { Page, PageInjectContext } from "./lib/PageRouter/Page";
@@ -19,4 +20,8 @@ import { NvlContainer } from "./elements/nvl/NvlContainer";
19
20
  import { DefaultNvlContainer } from "./elements/nvl/DefaultNvlContainer";
20
21
  import { NvlDialogList, DefaultNvlDialogItem } from "./elements/nvl/NvlDialogList";
21
22
  import { NvlProvider, useNvl, useNvlDialogs, useIsNvlMode, useIsNvlVisible } from "./elements/nvl/NvlContext";
22
- export { Isolated, usePreference, Stage, GameMenu, Item, Notifications, Texts, Nametag, Dialog, useDialog, useVoiceState, Page, Layout, LayoutRouterProvider, PageInjectContext, RootPath, FixedAspectRatioContainer, useKeyBinding, useLiveGame, NvlContainer, DefaultNvlContainer, NvlDialogList, DefaultNvlDialogItem, NvlProvider, useNvl, useNvlDialogs, useIsNvlMode, useIsNvlVisible, };
23
+ export type { DialogAvatarContext } from "./elements/say/Avatar";
24
+ export type { BaseTextsProps, EntryTextsProps, RawTextsProps, TextAppearanceProps, TextsPreviewInput, TextsPreviewLoop, TextsPreviewProps, TextsProps, } from "./elements/say/Sentence";
25
+ export type { NametagProps } from "./elements/say/Nametag";
26
+ export type { ItemProps } from "./elements/menu/UIMenu/Item";
27
+ export { Isolated, usePreference, Stage, GameMenu, Item, 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, };
@@ -21,4 +21,5 @@ export declare function GameProvider({ children, game }: {
21
21
  * @throws Error if used outside of GameProvider
22
22
  */
23
23
  export declare function useGame(): GameContextType;
24
+ export declare function useOptionalGame(): GameContextType | null;
24
25
  export {};