narraleaf-react 0.9.0 → 0.9.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.
Files changed (41) 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/player/Tasks.d.ts +4 -1
  26. package/dist/game/player/elements/Player.d.ts +1 -1
  27. package/dist/game/player/elements/menu/type.d.ts +1 -0
  28. package/dist/game/player/elements/say/Avatar.d.ts +13 -0
  29. package/dist/game/player/elements/say/Sentence.d.ts +70 -1
  30. package/dist/game/player/elements/say/UIDialog.d.ts +6 -2
  31. package/dist/game/player/elements/say/type.d.ts +4 -2
  32. package/dist/game/player/elements/say/useDialog.d.ts +3 -0
  33. package/dist/game/player/elements/type.d.ts +6 -0
  34. package/dist/game/player/gameState.d.ts +3 -0
  35. package/dist/game/player/lib/AudioManager.d.ts +1 -0
  36. package/dist/game/player/lib/ErrorFallback.d.ts +5 -1
  37. package/dist/game/player/libElements.d.ts +5 -2
  38. package/dist/game/player/provider/game-state.d.ts +1 -0
  39. package/dist/main.js +42 -40
  40. package/dist/util/data.d.ts +15 -2
  41. package/package.json +114 -107
@@ -4,12 +4,22 @@ import { Word } from "../../elements/character/word";
4
4
  import type { ScriptCtx } from "../../elements/script";
5
5
  import { Sound } from "../../elements/sound";
6
6
  import { Color, Font } from "../../types";
7
+ import type { DialogAvatar } from "../../elements/character/avatar";
8
+ /**
9
+ * User-provided runtime metadata attached to a sentence; not serialized with saves.
10
+ * Use plain serializable values when possible.
11
+ */
12
+ export type SentenceMetadata = Record<string, unknown>;
7
13
  export type SentenceConfig = {
8
14
  pause?: boolean | number;
9
15
  voice: Sound | null;
10
16
  character: Character | null;
11
17
  voiceId: string | number | null;
12
18
  color?: Color;
19
+ /** Optional runtime-only metadata for UI hooks and integrations */
20
+ metadata?: SentenceMetadata;
21
+ /** Optional per-line dialog avatar override. Use `false` to hide the avatar for this sentence. */
22
+ avatar?: DialogAvatar | false;
13
23
  } & Font;
14
24
  export type SentenceUserConfig = Partial<Omit<SentenceConfig, "voice"> & {
15
25
  voice: Sound | string | null | undefined;
@@ -20,6 +30,10 @@ export type StaticWord<T extends string | DynamicWord | Pausing = string | Dynam
20
30
  export type SingleWord = StaticWord | DynamicWord;
21
31
  export type SentencePrompt = SingleWord[] | SingleWord;
22
32
  export declare class Sentence {
33
+ /**
34
+ * Returns runtime-only user metadata from sentence config; undefined when not set.
35
+ */
36
+ getMetadata(): SentenceMetadata | undefined;
23
37
  /**
24
38
  * Build a new sentence from a prompt or mix of words, pauses, and dynamic data.
25
39
  * @param text - The sentence prompt used to render the dialogue.
@@ -4,8 +4,12 @@ import { DeepPartial } from "../../../util/data";
4
4
  import { Actionable } from "../action/actionable";
5
5
  import { Chained, Proxied } from "../action/chain";
6
6
  import { Sentence, SentencePrompt, SentenceUserConfig, SingleWord } from "../elements/character/sentence";
7
+ import type { CharacterPortraitConfig, DialogAvatar } from "../elements/character/avatar";
8
+ import type { Image } from "../elements/displayable/image";
7
9
  export type CharacterConfig = {
8
10
  color?: Color;
11
+ avatar?: DialogAvatar | false;
12
+ portraits: (Image | CharacterPortraitConfig)[];
9
13
  };
10
14
  export interface Character {
11
15
  (content: string, config?: SentenceUserConfig): Proxied<Character, Chained<LogicAction.Actions>>;
@@ -58,6 +62,32 @@ export declare class Character extends Actionable<CharacterStateData, Character>
58
62
  * ```
59
63
  */
60
64
  setName(name: string): Proxied<Character, Chained<LogicAction.Actions>>;
65
+ /**
66
+ * Set the avatar strategy used by dialogs for this character.
67
+ * @param avatar - Image source, resolver, `false` to hide by default, or `null` for no avatar.
68
+ * @example
69
+ * ```ts
70
+ * character.setAvatar("alice-avatar.png");
71
+ * ```
72
+ */
73
+ setAvatar(avatar: DialogAvatar | false | null): this;
74
+ /**
75
+ * Register a portrait image as a possible visual source for this character's dialog avatar.
76
+ * @param image - The stage image that represents the character.
77
+ * @param config - Optional avatar override for this portrait.
78
+ * @example
79
+ * ```ts
80
+ * character.addPortrait(aliceSprite, { avatar: "alice-happy-avatar.png" });
81
+ * ```
82
+ */
83
+ addPortrait(image: Image, config?: {
84
+ avatar?: DialogAvatar;
85
+ }): this;
86
+ /**
87
+ * Replace all portrait bindings for this character.
88
+ * @param portraits - Stage images or image/avatar pairs.
89
+ */
90
+ setPortraits(portraits: (Image | CharacterPortraitConfig)[]): this;
61
91
  apply(content: string, config?: SentenceUserConfig): Proxied<Character, Chained<LogicAction.Actions>>;
62
92
  apply(content: Sentence): Proxied<Character, Chained<LogicAction.Actions>>;
63
93
  apply(content: SentencePrompt, config?: SentenceUserConfig): Proxied<Character, Chained<LogicAction.Actions>>;
@@ -4,6 +4,7 @@ import { Chained, Proxied } from "../../action/chain";
4
4
  import { LogicAction } from "../../action/logicAction";
5
5
  import { EventfulDisplayable } from "../../../player/elements/displayable/type";
6
6
  import type { TransformDefinitions } from "../../elements/transform/type";
7
+ import type { ImageSrc } from "../../types";
7
8
  export declare abstract class Displayable<StateData extends Record<string, any>, Self extends Displayable<any, any, any>, TransformType extends TransformDefinitions.Types = TransformDefinitions.Types> extends Actionable<StateData, Self> implements EventfulDisplayable {
8
9
  /**
9
10
  * Set Image Position
@@ -92,6 +93,83 @@ export declare abstract class Displayable<StateData extends Record<string, any>,
92
93
  * ```
93
94
  */
94
95
  opacity(opacity: number, duration?: number, easing?: TransformDefinitions.EasingDefinition): Proxied<Self, Chained<LogicAction.Actions>>;
96
+ /**
97
+ * Apply visual effects to the Displayable.
98
+ *
99
+ * This is the low-level effect entry. Resource-aware helpers such as
100
+ * {@link Displayable.mask} should be preferred when an effect depends on an image source.
101
+ *
102
+ * @chainable
103
+ */
104
+ effect(effect: TransformDefinitions.VisualEffectTransformProps, options?: TransformDefinitions.VisualEffectOptions): Proxied<Self, Chained<LogicAction.Actions, Self>>;
105
+ /**
106
+ * Apply an image mask to the Displayable.
107
+ *
108
+ * The source is registered for image preload and resolved to a CSS `url(...)` mask image.
109
+ *
110
+ * @chainable
111
+ */
112
+ mask(src: ImageSrc, options?: TransformDefinitions.MaskOptions): Proxied<Self, Chained<LogicAction.Actions, Self>>;
113
+ /**
114
+ * Clear the current CSS mask from the Displayable.
115
+ *
116
+ * @chainable
117
+ */
118
+ clearMask(options?: TransformDefinitions.VisualEffectOptions): Proxied<Self, Chained<LogicAction.Actions, Self>>;
119
+ /**
120
+ * Apply a CSS clip-path to the Displayable.
121
+ *
122
+ * @chainable
123
+ */
124
+ clip(clipPath: TransformDefinitions.VisualEffectTransformProps["clipPath"], options?: TransformDefinitions.VisualEffectOptions): Proxied<Self, Chained<LogicAction.Actions, Self>>;
125
+ /**
126
+ * Clear the current CSS clip-path from the Displayable.
127
+ *
128
+ * @chainable
129
+ */
130
+ clearClip(options?: TransformDefinitions.VisualEffectOptions): Proxied<Self, Chained<LogicAction.Actions, Self>>;
131
+ /**
132
+ * Reveal the Displayable with an animated circular clip-path.
133
+ *
134
+ * @chainable
135
+ */
136
+ circleReveal(options?: TransformDefinitions.CircleRevealOptions): Proxied<Self, Chained<LogicAction.Actions, Self>>;
137
+ /**
138
+ * Close the Displayable with an animated circular clip-path.
139
+ *
140
+ * @chainable
141
+ */
142
+ circleClose(options?: TransformDefinitions.CircleCloseOptions): Proxied<Self, Chained<LogicAction.Actions, Self>>;
143
+ /**
144
+ * Reveal or close the Displayable with an animated directional wipe.
145
+ *
146
+ * @chainable
147
+ */
148
+ wipe(options?: TransformDefinitions.WipeOptions): Proxied<Self, Chained<LogicAction.Actions, Self>>;
149
+ /**
150
+ * Apply a CSS filter to the Displayable.
151
+ *
152
+ * @chainable
153
+ */
154
+ filter(filter: TransformDefinitions.VisualEffectTransformProps["filter"], options?: TransformDefinitions.VisualEffectOptions): Proxied<Self, Chained<LogicAction.Actions, Self>>;
155
+ /**
156
+ * Clear the current CSS filter from the Displayable.
157
+ *
158
+ * @chainable
159
+ */
160
+ clearFilter(options?: TransformDefinitions.VisualEffectOptions): Proxied<Self, Chained<LogicAction.Actions, Self>>;
161
+ /**
162
+ * Apply a CSS backdrop-filter to the Displayable.
163
+ *
164
+ * @chainable
165
+ */
166
+ backdrop(backdropFilter: TransformDefinitions.VisualEffectTransformProps["backdropFilter"], options?: TransformDefinitions.VisualEffectOptions): Proxied<Self, Chained<LogicAction.Actions, Self>>;
167
+ /**
168
+ * Apply a CSS mix-blend-mode to the Displayable.
169
+ *
170
+ * @chainable
171
+ */
172
+ blend(mixBlendMode: TransformDefinitions.VisualEffectTransformProps["mixBlendMode"], options?: TransformDefinitions.VisualEffectOptions): Proxied<Self, Chained<LogicAction.Actions, Self>>;
95
173
  /**
96
174
  * Apply a transform to the Displayable
97
175
  * @chainable
@@ -101,6 +179,12 @@ export declare abstract class Displayable<StateData extends Record<string, any>,
101
179
  * ```
102
180
  */
103
181
  transform(transform: Transform<TransformType>): Proxied<Self, Chained<LogicAction.Actions, Self>>;
182
+ private registerEffectSrc;
183
+ private static toCSSUrl;
184
+ private static extractCSSUrls;
185
+ private static createClipPathTransform;
186
+ private static circleClipPath;
187
+ private static wipeClipPath;
104
188
  /**
105
189
  * Show the Displayable
106
190
  *
@@ -1,5 +1,5 @@
1
1
  import type { TransformDefinitions } from "../../elements/transform/type";
2
- import { Color, CommonDisplayableConfig, ImageSrc } from "../../types";
2
+ import { Color, ImageSrc } from "../../types";
3
3
  import { LogicAction } from "../../game";
4
4
  import { FlexibleTuple, SelectElementFromEach } from "../../../../util/data";
5
5
  import { Chained, Proxied } from "../../action/chain";
@@ -14,7 +14,7 @@ export type TagDefinitionObject<T extends TagGroupDefinition> = {
14
14
  resolve: TagSrcResolver<T>;
15
15
  };
16
16
  type ImageSrcType<T extends TagGroupDefinition | null = TagGroupDefinition | null> = T extends TagGroupDefinition ? TagDefinition<T> : (Color | ImageSrc);
17
- export interface IImageUserConfig<Tag extends TagGroupDefinition | null = TagGroupDefinition | null> extends CommonDisplayableConfig {
17
+ export interface IImageUserConfig<Tag extends TagGroupDefinition | null = TagGroupDefinition | null> extends TransformDefinitions.ImageTransformProps {
18
18
  /**
19
19
  * The name of the image, only for debugging purposes
20
20
  */
@@ -1,4 +1,4 @@
1
- import { Color, CommonDisplayableConfig } from "../../types";
1
+ import { Color } from "../../types";
2
2
  import { Chained, Proxied } from "../../action/chain";
3
3
  import { LogicAction } from "../../action/logicAction";
4
4
  import type { TransformDefinitions } from "../../elements/transform/type";
@@ -16,7 +16,7 @@ export type TextState = {
16
16
  display: boolean;
17
17
  text: string;
18
18
  };
19
- export interface ITextUserConfig extends CommonDisplayableConfig {
19
+ export interface ITextUserConfig extends TransformDefinitions.TextTransformProps {
20
20
  /**
21
21
  * Where to align the text horizontally
22
22
  * @default "center"
@@ -1,4 +1,3 @@
1
- import { CommonDisplayableConfig } from "../types";
2
1
  import { LogicAction } from "../action/logicAction";
3
2
  import { TransformDefinitions } from "../elements/transform/type";
4
3
  import { Displayable } from "../elements/displayable/displayable";
@@ -6,7 +5,7 @@ import { EventfulDisplayable } from "../../player/elements/displayable/type";
6
5
  import { Image } from "../elements/displayable/image";
7
6
  import { Text } from "../elements/displayable/text";
8
7
  import { Chained, Proxied } from "../action/chain";
9
- export interface ILayerUserConfig extends CommonDisplayableConfig {
8
+ export interface ILayerUserConfig extends TransformDefinitions.ImageTransformProps {
10
9
  /**
11
10
  * The z-index of the layer, higher z-index will be rendered on top of the lower z-index, allows negative values.
12
11
  *
@@ -3,12 +3,13 @@ import { Color, ImageSrc } from "../types";
3
3
  import { LogicAction } from "../action/logicAction";
4
4
  import { Sound, VoiceIdMap, VoiceSrcGenerator } from "../elements/sound";
5
5
  import { Image } from "../elements/displayable/image";
6
- import { ActionStatements, Persistent } from "../common/core";
7
6
  import { Chained, Proxied } from "../action/chain";
8
7
  import { ImageTransition } from "../elements/transition/transitions/image/imageTransition";
9
8
  import { Layer } from "../elements/layer";
10
9
  import { NVLToken } from "./nvl";
11
10
  import type { TransformDefinitions } from "../elements/transform/type";
11
+ import type { ActionStatements } from "../elements/type";
12
+ import type { Persistent } from "../elements/persistent";
12
13
  export interface ISceneUserConfig {
13
14
  /**
14
15
  * Background music
@@ -1,4 +1,3 @@
1
- import type { CommonDisplayableConfig } from "../../types";
2
1
  import { TransformDefinitions } from "./type";
3
2
  import { CSSProps } from "../../elements/transition/type";
4
3
  type OverwriteMap = {
@@ -8,7 +7,7 @@ export type OverwriteDefinition = {
8
7
  [K in keyof OverwriteMap]?: OverwriteHandler<OverwriteMap[K]>;
9
8
  };
10
9
  type OverwriteHandler<T> = (value: Partial<TransformDefinitions.Types>) => T;
11
- export declare class Transform<T extends TransformDefinitions.Types = CommonDisplayableConfig> {
10
+ export declare class Transform<T extends TransformDefinitions.Types = TransformDefinitions.Types> {
12
11
  /**
13
12
  * Apply transform immediately
14
13
  */
@@ -30,7 +29,7 @@ export declare class Transform<T extends TransformDefinitions.Types = CommonDisp
30
29
  * @param config - The config for the transform.
31
30
  * @returns A new transform with the given config.
32
31
  */
33
- static create<T extends TransformDefinitions.Types = CommonDisplayableConfig>(config?: Partial<TransformDefinitions.TransformConfig>): Transform<T>;
32
+ static create<T extends TransformDefinitions.Types = TransformDefinitions.Types>(config?: Partial<TransformDefinitions.TransformConfig>): Transform<T>;
34
33
  /**
35
34
  * @example
36
35
  * ```ts
@@ -124,5 +123,29 @@ export declare class Transform<T extends TransformDefinitions.Types = CommonDisp
124
123
  * @returns {this} The current Transform instance for method chaining.
125
124
  */
126
125
  fontColor(fontColor: TransformDefinitions.Types["fontColor"]): this;
126
+ /**
127
+ * Set visual effect fields in the current staging sequence.
128
+ */
129
+ effect(effect: TransformDefinitions.VisualEffectTransformProps): this;
130
+ /**
131
+ * Set the CSS mask image of the current staging sequence.
132
+ */
133
+ maskImage(maskImage: TransformDefinitions.Types["maskImage"]): this;
134
+ /**
135
+ * Set the CSS clip-path of the current staging sequence.
136
+ */
137
+ clipPath(clipPath: TransformDefinitions.Types["clipPath"]): this;
138
+ /**
139
+ * Set the CSS filter of the current staging sequence.
140
+ */
141
+ filter(filter: TransformDefinitions.Types["filter"]): this;
142
+ /**
143
+ * Set the CSS backdrop-filter of the current staging sequence.
144
+ */
145
+ backdropFilter(backdropFilter: TransformDefinitions.Types["backdropFilter"]): this;
146
+ /**
147
+ * Set the CSS mix-blend-mode of the current staging sequence.
148
+ */
149
+ mixBlendMode(mixBlendMode: TransformDefinitions.Types["mixBlendMode"]): this;
127
150
  }
128
151
  export {};
@@ -1,4 +1,5 @@
1
1
  import { Color, CommonDisplayableConfig } from "../../types";
2
+ import type React from "react";
2
3
  export declare namespace TransformDefinitions {
3
4
  type BezierDefinition = [number, number, number, number];
4
5
  type CustomEasingFunction = (t: number) => number;
@@ -17,10 +18,37 @@ export declare namespace TransformDefinitions {
17
18
  repeat?: number;
18
19
  repeatDelay?: number;
19
20
  };
20
- type ImageTransformProps = CommonDisplayableConfig & {};
21
+ type VisualEffectTransformProps = {
22
+ maskImage?: React.CSSProperties["maskImage"];
23
+ maskSize?: React.CSSProperties["maskSize"];
24
+ maskPosition?: React.CSSProperties["maskPosition"];
25
+ maskRepeat?: React.CSSProperties["maskRepeat"];
26
+ maskMode?: React.CSSProperties["maskMode"];
27
+ clipPath?: React.CSSProperties["clipPath"];
28
+ filter?: React.CSSProperties["filter"];
29
+ backdropFilter?: React.CSSProperties["backdropFilter"];
30
+ mixBlendMode?: React.CSSProperties["mixBlendMode"];
31
+ };
32
+ type VisualEffectOptions = Partial<CommonTransformProps>;
33
+ type MaskOptions = VisualEffectOptions & Pick<VisualEffectTransformProps, "maskSize" | "maskPosition" | "maskRepeat" | "maskMode">;
34
+ type WipeDirection = "left" | "right" | "top" | "bottom";
35
+ type CircleClipOptions = VisualEffectOptions & {
36
+ center?: string;
37
+ from?: number;
38
+ to?: number;
39
+ clearClip?: boolean;
40
+ };
41
+ type CircleRevealOptions = CircleClipOptions;
42
+ type CircleCloseOptions = CircleClipOptions;
43
+ type WipeOptions = VisualEffectOptions & {
44
+ direction?: WipeDirection;
45
+ reverse?: boolean;
46
+ clearClip?: boolean;
47
+ };
48
+ type ImageTransformProps = CommonDisplayableConfig & VisualEffectTransformProps;
21
49
  type TextTransformProps = CommonDisplayableConfig & {
22
50
  fontColor?: Color;
23
- };
51
+ } & VisualEffectTransformProps;
24
52
  type Types = CommonDisplayableConfig & ImageTransformProps & TextTransformProps;
25
53
  type SequenceProps<T> = Partial<T>;
26
54
  type SequenceOptions = Partial<CommonTransformProps>;
@@ -0,0 +1,38 @@
1
+ import { TransitionAnimationType, TransitionTask } from "../../../../elements/transition/type";
2
+ import { TransformDefinitions } from "../../../../elements/transform/type";
3
+ import { ImageTransition } from "../../../../elements/transition/transitions/image/imageTransition";
4
+ type AnimationType = [TransitionAnimationType.Number];
5
+ export type MaskTransitionCircleOptions = {
6
+ duration: number;
7
+ easing?: TransformDefinitions.EasingDefinition;
8
+ center?: string;
9
+ from?: number;
10
+ to?: number;
11
+ };
12
+ export type MaskTransitionWipeOptions = {
13
+ duration: number;
14
+ easing?: TransformDefinitions.EasingDefinition;
15
+ direction?: TransformDefinitions.WipeDirection;
16
+ reverse?: boolean;
17
+ };
18
+ export declare class MaskTransition extends ImageTransition<AnimationType> {
19
+ private duration;
20
+ private easing;
21
+ private clipPathResolver;
22
+ private constructor();
23
+ /**
24
+ * Reveal the target image through an animated circular clip-path.
25
+ */
26
+ static circle(options: MaskTransitionCircleOptions): MaskTransition;
27
+ /**
28
+ * Reveal or close the target image through an animated directional wipe.
29
+ */
30
+ static wipe(options: MaskTransitionWipeOptions): MaskTransition;
31
+ createTask(): TransitionTask<HTMLImageElement, AnimationType>;
32
+ copy(): MaskTransition;
33
+ private static lerp;
34
+ private static circleClipPath;
35
+ private static wipeClipPath;
36
+ private static formatNumber;
37
+ }
38
+ export {};
@@ -1,6 +1,6 @@
1
1
  import { Awaitable } from "../../util/data";
2
2
  import { GameStateGuard } from "./guard";
3
- type TimelineStatus = "pending" | "cancelled" | "resolved";
3
+ type TimelineStatus = "pending" | "cancelled" | "resolved" | "failed";
4
4
  export declare class Timeline {
5
5
  awaitable: Awaitable;
6
6
  guard?: GameStateGuard | undefined;
@@ -74,6 +74,7 @@ export declare class Timeline {
74
74
  private children;
75
75
  private _onResolved;
76
76
  private _onCancelled;
77
+ private _onFailed;
77
78
  private _onTimelineRegistered;
78
79
  private _ableToAttach;
79
80
  private _status;
@@ -82,8 +83,10 @@ export declare class Timeline {
82
83
  isSettled(): boolean;
83
84
  isResolved(): boolean;
84
85
  isCancelled(): boolean;
86
+ isFailed(): boolean;
85
87
  onResolved(callback: () => void): void;
86
88
  onCancelled(callback: () => void): void;
89
+ onFailed(callback: (error: unknown) => void): void;
87
90
  onSettled(callback: () => void): void;
88
91
  abort(): void;
89
92
  attachChild(arg0: Awaitable | Timeline): this;
@@ -1,4 +1,4 @@
1
1
  import "client-only";
2
2
  import { PlayerProps } from "../elements/type";
3
3
  import React from "react";
4
- export default function Player({ story, width, height, className, onReady, onEnd, onError, children, active, }: Readonly<PlayerProps>): React.JSX.Element;
4
+ export default function Player({ story, width, height, className, onReady, onPreloadedReady, onEnd, onError, children, active, }: Readonly<PlayerProps>): React.JSX.Element;
@@ -10,6 +10,7 @@ export interface MenuElementProps {
10
10
  afterChoose: (choice: Chosen) => void;
11
11
  state: GameState;
12
12
  words: Word<Pausing | string>[] | null;
13
+ renderPrompt?: boolean;
13
14
  }
14
15
  export interface IUserMenuProps {
15
16
  items: number[];
@@ -0,0 +1,13 @@
1
+ import type { Character } from "../../../nlcore/elements/character";
2
+ import type { Image } from "../../../nlcore/elements/displayable/image";
3
+ import React from "react";
4
+ export type DialogAvatarContext = {
5
+ visible: boolean;
6
+ src: string | null;
7
+ character: Character | null;
8
+ portrait: Image | null;
9
+ alt: string;
10
+ };
11
+ export declare function useAvatar(): DialogAvatarContext;
12
+ export declare function Avatar({ className, style, alt, ...props }: React.ImgHTMLAttributes<HTMLImageElement>): React.JSX.Element | null;
13
+ export default Avatar;
@@ -1,5 +1,5 @@
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";
@@ -16,6 +16,74 @@ type BaseTextsProps = {
16
16
  style?: React.CSSProperties;
17
17
  dialog?: DialogState;
18
18
  } & React.HTMLAttributes<HTMLDivElement>;
19
+ export type TextsPreviewInput = StaticWord<string | Pausing> | StaticWord<string | Pausing>[];
20
+ export type TextsPreviewLoop = boolean | {
21
+ /**
22
+ * Whether the preview restarts after the current type effect completes.
23
+ * @default true
24
+ */
25
+ enabled?: boolean;
26
+ /**
27
+ * Delay before the next preview cycle starts, in milliseconds.
28
+ * @default 1000
29
+ */
30
+ delay?: number;
31
+ };
32
+ export interface TextsPreviewProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
33
+ /**
34
+ * Static text or words to preview.
35
+ */
36
+ text?: TextsPreviewInput;
37
+ /**
38
+ * Sentence to preview. Dynamic words are not evaluated; pass `words` when
39
+ * previewing already-evaluated runtime content.
40
+ */
41
+ sentence?: Sentence;
42
+ /**
43
+ * Already-evaluated words, useful when previewing dynamic sentence content.
44
+ */
45
+ words?: Word<Pausing | string>[];
46
+ /**
47
+ * Whether the preview should use the rolling type effect.
48
+ * @default true
49
+ */
50
+ useTypeEffect?: boolean;
51
+ /**
52
+ * Loop behavior for settings screens and other static previews.
53
+ * @default true
54
+ */
55
+ loop?: TextsPreviewLoop;
56
+ /**
57
+ * Delay before replay when `loop` is `true`, in milliseconds.
58
+ * Ignored when `loop` is an object with `delay`.
59
+ * @default 1000
60
+ */
61
+ restartDelay?: number;
62
+ /**
63
+ * Characters per second used by the preview.
64
+ * @default current game's `cps` preference, or Game.DefaultPreference.cps outside GameProvider
65
+ */
66
+ cps?: number;
67
+ /**
68
+ * Speed multiplier used by the preview.
69
+ * @default current game's `gameSpeed` preference, or Game.DefaultPreference.gameSpeed outside GameProvider
70
+ */
71
+ gameSpeed?: number;
72
+ /**
73
+ * Duration for a pause without an explicit duration, in milliseconds.
74
+ * @default current game's `autoForwardDefaultPause` config, or Game.DefaultConfig.autoForwardDefaultPause outside GameProvider
75
+ */
76
+ pauseDuration?: number;
77
+ /**
78
+ * Fallback color when neither the word nor the sentence defines one.
79
+ */
80
+ defaultColor?: Color;
81
+ fontSize?: React.CSSProperties["fontSize"];
82
+ fontWeight?: React.CSSProperties["fontWeight"];
83
+ fontWeightBold?: React.CSSProperties["fontWeight"];
84
+ fontFamily?: React.CSSProperties["fontFamily"];
85
+ onCompleted?: () => void;
86
+ }
19
87
  /**
20
88
  * Props-based wrapper component
21
89
  * Provides a clean interface for direct prop usage
@@ -36,6 +104,7 @@ export type EntryTextsProps = BaseTextsProps & {
36
104
  useTypeEffect: boolean;
37
105
  isActive: boolean;
38
106
  };
107
+ 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;
39
108
  export declare function RawTexts(props: BaseTextsProps): React.JSX.Element;
40
109
  /**
41
110
  * Context-based wrapper component
@@ -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.
@@ -39,6 +39,12 @@ export interface PlayerProps {
39
39
  * only called each lifecycle once
40
40
  */
41
41
  onReady?: (ctx: PlayerEventContext) => void;
42
+ /**
43
+ * Once the internal preload pass is ready and the Player has committed that state.
44
+ *
45
+ * only called each lifecycle once
46
+ */
47
+ onPreloadedReady?: (ctx: PlayerEventContext) => void;
42
48
  /**
43
49
  * Once the game is ended
44
50
  *
@@ -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;
@@ -182,6 +183,7 @@ export declare class GameState {
182
183
  getSceneElements(): PlayerStateElement[];
183
184
  getLastScene(): Scene | null;
184
185
  getCurrentScene(): Scene | null;
186
+ findCurrentPortraitForCharacter(character: Character): NormalizedCharacterPortraitConfig | null;
185
187
  sceneExists(scene?: Scene): boolean;
186
188
  isSceneActive(scene: Scene): boolean;
187
189
  wait(ms: number): Promise<void>;
@@ -317,6 +319,7 @@ export declare class GameState {
317
319
  private syncNvlDerivedState;
318
320
  private emitNvlStateChange;
319
321
  private resolveNvlAdvance;
322
+ private isDisplayableVisible;
320
323
  private createWaitableAction;
321
324
  private sceneNotFound;
322
325
  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.