narraleaf-react 0.4.0 → 0.4.2

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 CHANGED
@@ -1,10 +1,15 @@
1
- ![](docs/nlr-logo-banner.png)
1
+ <picture>
2
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/NarraLeaf/.github/refs/heads/master/doc/banner-md-transparent.png">
3
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/NarraLeaf/.github/refs/heads/master/doc/banner-md-light.png">
4
+ <img alt="Fallback image description" src="https://raw.githubusercontent.com/NarraLeaf/.github/refs/heads/master/doc/banner-md-light.png">
5
+ </picture>
2
6
 
3
- # NarraLeaf-React
7
+ <h1 align="center">NarraLeaf-React</h1>
4
8
 
5
- English | [简体中文](docs/README.zh-CN.md)
9
+ <h4 align="center">A React visual novel player framework</h3>
10
+
11
+ <p align="center">English | <a href="docs/README.zh-CN.md">简体中文</a></p>
6
12
 
7
- A React visual novel player framework
8
13
 
9
14
  ## What is NarraLeaf-React?
10
15
 
@@ -46,7 +51,7 @@ scene1.action([
46
51
  johnSmith
47
52
  .say("Hello, world!")
48
53
  .say`This is my first ${b("NarraLeaf")} story.`
49
- .say`Start editing ${c("src/story.js", "#0000ff")} and enjoy the journey!`,
54
+ .say`Start editing ${c("src/story.js", "#00f")} and enjoy the journey!`,
50
55
 
51
56
  /**
52
57
  * John Doe: Also, don't forget to check out the documentation!
@@ -100,6 +105,9 @@ npm install narraleaf-react
100
105
  - [Conditional](https://react.narraleaf.com/documentation/basic/conditional)
101
106
  - [Voice](https://react.narraleaf.com/documentation/basic/voice)
102
107
  - [Manage Preferences](https://react.narraleaf.com/documentation/basic/manage-preferences)
108
+ - [Solutions](https://react.narraleaf.com/documentation/solutions)
109
+ - [Customizing the font](https://react.narraleaf.com/documentation/solutions/font)
110
+ - [Migration from Ren'Py](https://react.narraleaf.com/documentation/solutions/from-renpy)
103
111
  - [Core](https://react.narraleaf.com/documentation/core)
104
112
  - [Elements](https://react.narraleaf.com/documentation/core/elements)
105
113
  - [Scene](https://react.narraleaf.com/documentation/core/elements/scene)
@@ -116,13 +124,16 @@ npm install narraleaf-react
116
124
  - [Text](https://react.narraleaf.com/documentation/core/elements/text)
117
125
  - [Persistent](https://react.narraleaf.com/documentation/core/elements/persistent)
118
126
  - [Story](https://react.narraleaf.com/documentation/core/elements/story)
127
+ - [Displayable](https://react.narraleaf.com/documentation/core/elements/displayable)
128
+ - [Layer](https://react.narraleaf.com/documentation/core/elements/layer)
129
+ - [Service](https://react.narraleaf.com/documentation/core/elements/service)
130
+ - [Video](https://react.narraleaf.com/documentation/core/elements/video)
119
131
  - [Animation](https://react.narraleaf.com/documentation/core/animation)
120
132
  - [Game](https://react.narraleaf.com/documentation/core/game)
133
+ - [Plugin](https://react.narraleaf.com/documentation/core/plugin)
134
+ - [Utils](https://react.narraleaf.com/documentation/core/utils)
121
135
  - [Player](https://react.narraleaf.com/documentation/player)
122
- - [Customization](https://react.narraleaf.com/documentation/custom)
123
- - [Migration](https://react.narraleaf.com/documentation/migration)
124
- - [From Ren'Py](https://react.narraleaf.com/documentation/migration/from-renpy)
125
- - Info
136
+ - About
126
137
  - [License](https://react.narraleaf.com/documentation/info/license)
127
138
  - [Incompatible Changes](https://react.narraleaf.com/documentation/info/incompatible-changes)
128
139
 
@@ -10,7 +10,7 @@ type GameElementHistory = {
10
10
  voice: string | null;
11
11
  } | {
12
12
  type: "menu";
13
- text: string;
13
+ text: string | null;
14
14
  selected: string;
15
15
  };
16
16
  export type GameHistory = GameHistoryAction & {
@@ -32,6 +32,15 @@ import { LayerAction } from "../action/actions/layerAction";
32
32
  import { ExposedStateType } from "../../player/type";
33
33
  import { Video } from "../elements/video";
34
34
  import { VideoAction } from "../action/actions/videoAction";
35
+ export interface LogicActionInterface {
36
+ DisplayableElements: Text | Image | Layer | AbstractDisplayable<any, any>;
37
+ DisplayableExposed: ExposedStateType.image | ExposedStateType.layer | ExposedStateType.text;
38
+ GameElement: Character | Scene | Story | Image | Condition | Script | Menu | Sound | Control | Text | AbstractDisplayable<any, any> | Persistent<any> | ServiceSkeleton | Video;
39
+ Actions: TypedAction | CharacterAction | ConditionAction | ImageAction | SceneAction | ScriptAction | StoryAction | MenuAction | SoundAction | ControlAction | TextAction | DisplayableAction | PersistentAction | ServiceAction | LayerAction | VideoAction;
40
+ ActionTypes: Values<typeof CharacterActionTypes> | Values<typeof ConditionActionTypes> | Values<typeof ImageActionTypes> | Values<typeof SceneActionTypes> | Values<typeof ScriptActionTypes> | Values<typeof StoryActionTypes> | Values<typeof MenuActionTypes> | Values<typeof SoundAction.ActionTypes> | Values<typeof ControlAction.ActionTypes> | Values<typeof TextAction.ActionTypes> | Values<typeof DisplayableActionTypes> | Values<typeof PersistentActionTypes> | StringKeyOf<ServiceActionContentType> | Values<typeof LayerActionTypes> | Values<typeof VideoActionTypes>;
41
+ ActionContents: CharacterActionContentType & ConditionActionContentType & ImageActionContentType & SceneActionContentType & ScriptActionContentType & StoryActionContentType & MenuActionContentType & SoundActionContentType & ControlActionContentType & TextActionContentType & DisplayableActionContentType & PersistentActionContentType & ServiceActionContentType & LayerActionContentType & VideoActionContentType;
42
+ }
43
+ export declare const LogicAction: {};
35
44
  export declare namespace LogicAction {
36
45
  type DisplayableElements = Text | Image | Layer | AbstractDisplayable<any, any>;
37
46
  type DisplayableExposed = ExposedStateType.image | ExposedStateType.layer | ExposedStateType.text;
@@ -40,3 +49,4 @@ export declare namespace LogicAction {
40
49
  type ActionTypes = Values<typeof CharacterActionTypes> | Values<typeof ConditionActionTypes> | Values<typeof ImageActionTypes> | Values<typeof SceneActionTypes> | Values<typeof ScriptActionTypes> | Values<typeof StoryActionTypes> | Values<typeof MenuActionTypes> | Values<typeof SoundAction.ActionTypes> | Values<typeof ControlAction.ActionTypes> | Values<typeof TextAction.ActionTypes> | Values<typeof DisplayableActionTypes> | Values<typeof PersistentActionTypes> | StringKeyOf<ServiceActionContentType> | Values<typeof LayerActionTypes> | Values<typeof VideoActionTypes>;
41
50
  type ActionContents = CharacterActionContentType & ConditionActionContentType & ImageActionContentType & SceneActionContentType & ScriptActionContentType & StoryActionContentType & MenuActionContentType & SoundActionContentType & ControlActionContentType & TextActionContentType & DisplayableActionContentType & PersistentActionContentType & ServiceActionContentType & LayerActionContentType & VideoActionContentType;
42
51
  }
52
+ export type LogicAction = typeof LogicAction;
@@ -1,7 +1,9 @@
1
- import { TransformDefinitions } from "../elements/transform/type";
2
- import { Origins } from "../elements/story";
3
1
  import { ServiceHandlerCtx } from "../elements/service";
2
+ import { Origins } from "../elements/story";
3
+ import { TransformDefinitions } from "../elements/transform/type";
4
4
  import { IGamePluginRegistry } from "../game/plugin/plugin";
5
5
  import { LiveGameEventToken } from "../types";
6
+ import { GameHistory } from "../action/gameHistory";
7
+ import { GameConfig } from "../gameTypes";
6
8
  export * from "../elements/type";
7
- export type { TransformDefinitions, Origins, ServiceHandlerCtx, IGamePluginRegistry, LiveGameEventToken, };
9
+ export type { GameHistory, IGamePluginRegistry, LiveGameEventToken, Origins, ServiceHandlerCtx, TransformDefinitions, GameConfig, };
@@ -1,9 +1,9 @@
1
- import { Sound } from "../../elements/sound";
2
1
  import type { Character } from "../../elements/character";
2
+ import { Pausing } from "../../elements/character/pause";
3
3
  import { Word } from "../../elements/character/word";
4
- import { Color, Font } from "../../types";
5
4
  import type { ScriptCtx } from "../../elements/script";
6
- import { Pausing } from "../../elements/character/pause";
5
+ import { Sound } from "../../elements/sound";
6
+ import { Color, Font } from "../../types";
7
7
  export type SentenceConfig = {
8
8
  pause?: boolean | number;
9
9
  voice: Sound | null;
@@ -13,7 +13,7 @@ export type Choice = {
13
13
  prompt: Sentence;
14
14
  };
15
15
  export type MenuData = {
16
- prompt: Sentence;
16
+ prompt: Sentence | null;
17
17
  choices: Choice[];
18
18
  };
19
19
  export declare class Menu extends Actionable<any, Menu> {
@@ -23,9 +23,11 @@ export declare class Menu extends Actionable<any, Menu> {
23
23
  * @returns A new menu
24
24
  */
25
25
  static prompt(prompt: SentencePrompt | Sentence, config?: MenuConfig): Menu;
26
+ static choose(arg0: Sentence | MenuChoice | SentencePrompt, arg1?: ChainedActions): Proxied<Menu, Chained<LogicAction.Actions>>;
26
27
  constructor(prompt: SentencePrompt, config?: MenuConfig);
27
28
  constructor(prompt: Sentence, config?: MenuConfig);
28
29
  constructor(prompt: SentencePrompt | Sentence, config: MenuConfig);
30
+ constructor(prompt: null, config?: MenuConfig);
29
31
  /**
30
32
  * Add a choice to the menu
31
33
  * @example
@@ -37,4 +39,5 @@ export declare class Menu extends Actionable<any, Menu> {
37
39
  choose(choice: MenuChoice): Proxied<Menu, Chained<LogicAction.Actions>>;
38
40
  choose(prompt: Sentence, action: ChainedActions): Proxied<Menu, Chained<LogicAction.Actions>>;
39
41
  choose(prompt: SentencePrompt, action: ChainedActions): Proxied<Menu, Chained<LogicAction.Actions>>;
42
+ choose(arg0: Sentence | MenuChoice | SentencePrompt, arg1?: ChainedActions): Proxied<Menu, Chained<LogicAction.Actions>>;
40
43
  }
@@ -8,9 +8,29 @@ declare enum GameSettingsNamespace {
8
8
  game = "game"
9
9
  }
10
10
  export type GamePreference = {
11
+ /**
12
+ * If true, the game will automatically forward to the next sentence when the player has finished the current sentence
13
+ * @default false
14
+ */
11
15
  autoForward: boolean;
16
+ /**
17
+ * If true, the game will allow the player to skip the dialog
18
+ * @default true
19
+ */
12
20
  skip: boolean;
21
+ /**
22
+ * If true, the game will show the dialog
23
+ * @default true
24
+ */
13
25
  showDialog: boolean;
26
+ /**
27
+ * The multiplier of the dialog speed
28
+ *
29
+ * Dialog speed will apply to:
30
+ * - The text speed
31
+ * - The auto-forward delay
32
+ */
33
+ gameSpeed: number;
14
34
  };
15
35
  export type GameHooks = {
16
36
  /**
@@ -28,36 +28,6 @@ export interface SavedGame {
28
28
  };
29
29
  }
30
30
  export type GameConfig = {
31
- app: {
32
- debug: boolean;
33
- /**
34
- * Log level for the logger
35
- * Set to true to enable all logs
36
- */
37
- logger: {
38
- log: boolean;
39
- info: boolean;
40
- warn: boolean;
41
- error: boolean;
42
- debug: boolean;
43
- trace: boolean;
44
- verbose: boolean;
45
- } | boolean;
46
- /**
47
- * If true, the game will show the inspector when you hover over the element
48
- */
49
- inspector: boolean;
50
- /**
51
- * The config of {@link GameStateGuard}
52
- */
53
- guard: GuardConfig;
54
- /**
55
- * Quality of the screenshot, between 0 and 1
56
- * @default 1
57
- * @deprecated Moved to `$root.screenshotQuality`
58
- */
59
- screenshotQuality: number;
60
- };
61
31
  /**
62
32
  * The id of the container element for the game
63
33
  * @default "__narraleaf_content"
@@ -176,7 +146,6 @@ export type GameConfig = {
176
146
  /**
177
147
  * Quality of the screenshot, between 0 and 1
178
148
  * @default 1
179
- * @deprecated Moved to `$root.screenshotQuality`
180
149
  */
181
150
  screenshotQuality: number;
182
151
  /**
@@ -205,6 +174,13 @@ export type GameConfig = {
205
174
  * @default 3000
206
175
  */
207
176
  autoForwardDelay: number;
177
+ /**
178
+ * The default pause duration in milliseconds when auto-forward is enabled
179
+ *
180
+ * When auto-forward is enabled, any Pause without a custom duration will use this value
181
+ * @default 1000
182
+ */
183
+ autoForwardDefaultPause: number;
208
184
  /**
209
185
  * If true, when you press [GameConfig.player.skipKey], the game will skip the image transform
210
186
  * @default true
@@ -292,6 +268,60 @@ export type GameConfig = {
292
268
  * @default () => {}
293
269
  */
294
270
  onError: (error: Error) => void;
271
+ app: {
272
+ debug: boolean;
273
+ /**
274
+ * Log level for the logger
275
+ * Set to true to enable all logs
276
+ */
277
+ logger: {
278
+ log: boolean;
279
+ info: boolean;
280
+ warn: boolean;
281
+ error: boolean;
282
+ debug: boolean;
283
+ trace: boolean;
284
+ verbose: boolean;
285
+ } | boolean;
286
+ /**
287
+ * If true, the game will show the inspector when you hover over the element
288
+ */
289
+ inspector: boolean;
290
+ /**
291
+ * The config of {@link GameStateGuard}
292
+ */
293
+ guard: GuardConfig;
294
+ };
295
+ /**
296
+ * Default font size for the game
297
+ * @default "16px"
298
+ */
299
+ fontSize: React.CSSProperties["fontSize"];
300
+ /**
301
+ * Default font weight for the game
302
+ * @default 400
303
+ */
304
+ fontWeight: number;
305
+ /**
306
+ * Default font weight for the game
307
+ * @default 700
308
+ */
309
+ fontWeightBold: number;
310
+ /**
311
+ * Default font family for the game
312
+ * @default "sans-serif"
313
+ */
314
+ fontFamily: React.CSSProperties["fontFamily"];
315
+ /**
316
+ * Override the default stage
317
+ * @default null
318
+ */
319
+ stage: React.ReactNode | null;
320
+ /**
321
+ * The default color for the menu choices
322
+ * @default "#000"
323
+ */
324
+ defaultMenuChoiceColor: Color;
295
325
  };
296
326
  export type GameSettings = {
297
327
  volume: number;
@@ -1,5 +1,4 @@
1
1
  import "client-only";
2
- import "@player/lib/styles/style.css";
3
2
  import { PlayerProps } from "../elements/type";
4
3
  import React from "react";
5
4
  export default function Player({ story, width, height, className, onReady, onEnd, children, active, }: Readonly<PlayerProps>): React.JSX.Element;
@@ -2,5 +2,11 @@ import React from "react";
2
2
  export interface ItemProps {
3
3
  className?: string;
4
4
  style?: React.CSSProperties;
5
+ /**
6
+ * The keyboard binding for this item, see [Key_Values](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values) for more information
7
+ *
8
+ * When this key is pressed, the item will be selected and the action will be executed
9
+ */
10
+ bindKey?: string;
5
11
  }
6
- export default function Item({ className, style }: ItemProps): React.JSX.Element;
12
+ export default function Item({ className, style, bindKey }: ItemProps): React.JSX.Element;
@@ -5,11 +5,11 @@ import { Word } from "../../../nlcore/elements/character/word";
5
5
  import { Pausing } from "../../../nlcore/elements/character/pause";
6
6
  import { Chosen } from "../../type";
7
7
  export interface MenuElementProps {
8
- prompt: Sentence;
8
+ prompt: Sentence | null;
9
9
  choices: Choice[];
10
10
  afterChoose: (choice: Chosen) => void;
11
11
  state: GameState;
12
- words: Word<Pausing | string>[];
12
+ words: Word<Pausing | string>[] | null;
13
13
  }
14
14
  export interface IUserMenuProps {
15
15
  items: number[];
@@ -1,27 +1,11 @@
1
- import React from "react";
2
1
  import { DialogProps } from "../../elements/say/type";
3
- import { GameState } from "../../../nlcore/common/game";
4
- import { Sentence } from "../../../nlcore/elements/character/sentence";
5
- import { Word } from "../../../nlcore/elements/character/word";
6
- import { Pausing } from "../../../nlcore/elements/character/pause";
7
- /**
8
- * Props-based wrapper component
9
- * Provides a clean interface for direct prop usage
10
- */
11
- export interface RawDialogProps extends Omit<DialogProps, "onClick"> {
12
- sentence: Sentence;
13
- words: Word<Pausing | string>[];
14
- gameState: GameState;
15
- useTypeEffect?: boolean;
16
- onClick?: (skiped?: boolean) => void;
17
- onFinished?: () => void;
18
- }
19
- export declare function RawDialog(props: RawDialogProps): React.JSX.Element;
2
+ import React from "react";
3
+ export declare function RawDialog(props: DialogProps): React.JSX.Element;
20
4
  /**
21
5
  * Context-based wrapper component
22
6
  * Provides integration with the say context
23
7
  */
24
- export declare function Dialog({ children, ...props }: DialogProps): React.JSX.Element;
8
+ export declare function Dialog({ children, ...props }: DialogProps): React.JSX.Element | null;
25
9
  export default Dialog;
26
10
  /**
27
11
  * Default dialog component with Texts as children
@@ -1,9 +1,20 @@
1
- import React from "react";
2
- import { Word } from "../../../nlcore/elements/character/word";
3
1
  import { Pausing } from "../../../nlcore/elements/character/pause";
4
- import { DialogElementProps } from "./type";
5
- import { GameState } from "../../../../game/nlcore/common/game";
6
2
  import { Sentence } from "../../../nlcore/elements/character/sentence";
3
+ import { Word } from "../../../nlcore/elements/character/word";
4
+ import { GameState } from "../../../../game/nlcore/common/game";
5
+ import { Color } from "../../../../game/nlcore/types";
6
+ import React from "react";
7
+ import { DialogElementProps } from "./type";
8
+ import { DialogState } from "./UIDialog";
9
+ type BaseTextsProps = {
10
+ /**
11
+ * The default color of the text
12
+ */
13
+ defaultColor?: Color;
14
+ className?: string;
15
+ style?: React.CSSProperties;
16
+ dialog?: DialogState;
17
+ } & React.HTMLAttributes<HTMLDivElement>;
7
18
  /**
8
19
  * Props-based wrapper component
9
20
  * Provides a clean interface for direct prop usage
@@ -17,10 +28,10 @@ export interface TextsProps extends DialogElementProps {
17
28
  count?: number;
18
29
  words?: Word<Pausing | string>[];
19
30
  }
20
- export declare function RawTexts(props: TextsProps): React.JSX.Element;
31
+ export declare function RawTexts(props: BaseTextsProps): React.JSX.Element;
21
32
  /**
22
33
  * Context-based wrapper component
23
34
  * Provides integration with the sentence context
24
35
  */
25
- export declare function Texts(props: DialogElementProps): React.JSX.Element;
36
+ export declare function Texts(props: BaseTextsProps): React.JSX.Element;
26
37
  export default Texts;
@@ -1,3 +1,65 @@
1
+ import { Pausing } from "../../../nlcore/elements/character/pause";
2
+ import { Word } from "../../../nlcore/elements/character/word";
3
+ import { GameState } from "../../../../game/nlcore/common/game";
4
+ import { EventDispatcher } from "../../../../util/data";
1
5
  import React from "react";
2
- import { PlayerDialogProps } from "./type";
3
- export default function PlayerDialog({ action, onClick, useTypeEffect, gameState, }: Readonly<PlayerDialogProps>): React.JSX.Element;
6
+ import { DialogAction, DialogStateType, SayElementProps } from "./type";
7
+ type DialogEvents = {
8
+ "event:dialog.requestComplete": [];
9
+ "event:dialog.complete": [];
10
+ "event:dialog.forceSkip": [];
11
+ };
12
+ type DialogStateConfig = {
13
+ useTypeEffect: boolean;
14
+ action: DialogAction;
15
+ evaluatedWords: Word<Pausing | string>[];
16
+ gameState: GameState;
17
+ };
18
+ export declare class DialogState {
19
+ static Events: {
20
+ requestComplete: "event:dialog.requestComplete";
21
+ complete: "event:dialog.complete";
22
+ forceSkip: "event:dialog.forceSkip";
23
+ };
24
+ readonly config: Readonly<DialogStateConfig>;
25
+ readonly events: EventDispatcher<DialogEvents>;
26
+ private _state;
27
+ private _count;
28
+ private _forceSkipped;
29
+ private _idle;
30
+ private autoForwardScheduler;
31
+ constructor(config: DialogStateConfig);
32
+ get state(): DialogStateType;
33
+ get deps(): React.DependencyList;
34
+ isIdle(): boolean;
35
+ setIdle(idle: boolean): void;
36
+ /**
37
+ * Only for dialog component to call
38
+ *
39
+ * Calling this method will request the sentence to be completed
40
+ * If the sentence is already completed, it will exit the dialog
41
+ */
42
+ requestComplete(): void;
43
+ /**
44
+ * Only for dialog state to call
45
+ *
46
+ * Force the sentence to cancel/skip all the tasks
47
+ */
48
+ forceSkip(): void;
49
+ /**
50
+ * Only for sentence component to call
51
+ *
52
+ * Only call this method when the sentence is completed
53
+ * Calling this method will schedule the exit of the dialog
54
+ */
55
+ dispatchComplete(): void;
56
+ emitComplete(): void;
57
+ isEnded(): boolean;
58
+ setPause(pause: boolean): void;
59
+ isForceSkipped(): boolean;
60
+ tryScheduleAutoForward(): void;
61
+ cancelAutoForward(): void;
62
+ private scheduleAutoForward;
63
+ }
64
+ export default function PlayerDialog({ action, onFinished, useTypeEffect, gameState, }: Readonly<SayElementProps>): React.JSX.Element;
65
+ export {};
@@ -1,19 +1,4 @@
1
- import { GameState } from "../../../../game/nlcore/common/game";
2
- import { SayElementProps } from "./type";
3
1
  import React from "react";
4
- import { Sentence } from "../../../nlcore/elements/character/sentence";
5
- import { Word } from "../../../nlcore/elements/character/word";
6
- import { Pausing } from "../../../nlcore/elements/character/pause";
7
- export declare const SayContext: React.Context<SayElementProps | null>;
8
- export declare function useSayContext(): SayElementProps;
9
- export interface SentenceContext {
10
- sentence: Sentence;
11
- gameState: GameState;
12
- finished: boolean;
13
- useTypeEffect: boolean;
14
- onCompleted?: () => void;
15
- count: number;
16
- words: Word<Pausing | string>[];
17
- }
18
- export declare const SentenceContext: React.Context<SentenceContext | null>;
19
- export declare function useSentenceContext(): SentenceContext;
2
+ import { DialogState } from "./UIDialog";
3
+ export declare const DialogContext: React.Context<DialogState | null>;
4
+ export declare function useDialogContext(): DialogState;
@@ -6,23 +6,21 @@ import { Pausing } from "../../../nlcore/elements/character/pause";
6
6
  import React from "react";
7
7
  export interface SayElementProps {
8
8
  action: {
9
- sentence: Sentence;
9
+ sentence: Sentence | null;
10
10
  character: Character | null;
11
- words: Word<Pausing | string>[];
11
+ words: Word<Pausing | string>[] | null;
12
+ id?: string;
12
13
  };
13
14
  /**
15
+ * @deprecated
14
16
  * Callback function to be called when the player triggers the next action
15
17
  */
16
18
  onClick?: (skiped?: boolean) => void;
17
- onFinished?: () => void;
19
+ onFinished?: (skiped?: boolean) => void;
18
20
  useTypeEffect?: boolean;
19
21
  gameState: GameState;
20
22
  }
21
- export interface PlayerDialogProps extends SayElementProps {
22
- onFinished?: () => void;
23
- }
24
23
  export interface IDialogProps {
25
- isFinished: boolean;
26
24
  }
27
25
  export type DialogProps = {
28
26
  children: React.ReactNode;
@@ -33,3 +31,23 @@ export type DialogElementProps = {
33
31
  export interface IDialogElementProps extends React.HTMLAttributes<HTMLDivElement> {
34
32
  children?: never;
35
33
  }
34
+ export declare enum DialogStateType {
35
+ Pending = "pending",
36
+ Paused = "paused",
37
+ Ended = "ended"
38
+ }
39
+ export interface DialogContext {
40
+ gameState: GameState;
41
+ action: {
42
+ sentence: Sentence | null;
43
+ character: Character | null;
44
+ words: Word<Pausing | string>[] | null;
45
+ };
46
+ state: DialogStateType;
47
+ }
48
+ export type DialogAction = {
49
+ sentence: Sentence | null;
50
+ character: Character | null;
51
+ words: Word<Pausing | string>[] | null;
52
+ id?: string;
53
+ };
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Represents the context of a dialog, containing information about its completion status
3
+ * and the text content.
4
+ */
5
+ export type DialogContext = {
6
+ /** Whether the dialog has finished displaying */
7
+ done: boolean;
8
+ /** The text content of the dialog */
9
+ text: string;
10
+ };
11
+ /**
12
+ * A custom hook that provides access to the current dialog's state and content.
13
+ * It retrieves the dialog information from the sentence context and processes
14
+ * the words to generate the final text.
15
+ *
16
+ * @returns {DialogContext} An object containing the dialog's completion status and text content
17
+ */
18
+ export declare function useDialog(): {
19
+ done: boolean;
20
+ text: string;
21
+ };
@@ -125,7 +125,7 @@ export declare class GameState {
125
125
  text: string;
126
126
  };
127
127
  createMenu(menu: MenuData, afterChoose?: (choice: Chosen) => void, scene?: Scene): LiveGameEventToken & {
128
- prompt: string;
128
+ prompt: null | string;
129
129
  };
130
130
  createDisplayable(displayable: LogicAction.DisplayableElements, scene?: Scene | null, layer?: Layer | null): this;
131
131
  disposeDisplayable(displayable: LogicAction.DisplayableElements, scene?: Scene | null, layer?: Layer | null): this;
@@ -5,7 +5,7 @@ type PageRouterProps = Readonly<{
5
5
  /**
6
6
  * Page Router for NarraLeaf-React
7
7
  *
8
- * **Note**: only `Page` components are allowed as children, other components will be ignored.
8
+ * **Note**: only `Page` and `Stage` components are allowed as children, other components will be ignored.
9
9
  *
10
10
  * @example
11
11
  * ```tsx
@@ -7,5 +7,6 @@ import Item from "./elements/menu/UIMenu/Item";
7
7
  import Notifications from "./elements/notification/Notifications";
8
8
  import Texts from "./elements/say/Sentence";
9
9
  import Nametag from "./elements/say/Nametag";
10
- import Dialog from "../../game/player/elements/say/Dialog";
11
- export { Isolated, usePreference, Stage, Page, GameMenu, Item, Notifications, Texts, Nametag, Dialog, };
10
+ import Dialog from "./elements/say/Dialog";
11
+ import { useDialog } from "./elements/say/useDialog";
12
+ export { Isolated, usePreference, Stage, Page, GameMenu, Item, Notifications, Texts, Nametag, Dialog, useDialog, };
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from "./game/nlcore/common/core";
2
2
  export * from "./game/nlcore/common/player";
3
+ import "./styles/index.css";