@rohal12/spindle 0.23.0 → 0.24.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rohal12/spindle",
3
- "version": "0.23.0",
3
+ "version": "0.24.0",
4
4
  "type": "module",
5
5
  "description": "A Preact-based story format for Twine 2.",
6
6
  "license": "Unlicense",
@@ -1,11 +1,13 @@
1
1
  import { useEffect } from 'preact/hooks';
2
2
  import { useStoryStore } from '../store';
3
+ import { NobrContext } from '../markup/render';
3
4
  import { StoryInterface } from './StoryInterface';
4
5
  import { TriggerDialogHost } from './TriggerDialogHost';
5
6
 
6
7
  export function App() {
7
8
  const storyData = useStoryStore((s) => s.storyData);
8
9
  const currentPassage = useStoryStore((s) => s.currentPassage);
10
+ const nobr = useStoryStore((s) => s.nobr);
9
11
 
10
12
  useEffect(() => {
11
13
  const onKeyDown = (e: KeyboardEvent) => {
@@ -25,10 +27,16 @@ export function App() {
25
27
  return <div class="loading">Loading...</div>;
26
28
  }
27
29
 
28
- return (
30
+ const content = (
29
31
  <>
30
32
  <StoryInterface />
31
33
  <TriggerDialogHost />
32
34
  </>
33
35
  );
36
+
37
+ return nobr ? (
38
+ <NobrContext.Provider value={true}>{content}</NobrContext.Provider>
39
+ ) : (
40
+ content
41
+ );
34
42
  }
@@ -8,6 +8,7 @@ import {
8
8
  import {
9
9
  LocalsValuesContext,
10
10
  LocalsUpdateContext,
11
+ NobrContext,
11
12
  renderNodes,
12
13
  } from '../../markup/render';
13
14
  import { defineMacro } from '../../define-macro';
@@ -76,10 +77,12 @@ function ForIteration({
76
77
  }, []);
77
78
  const updater = useMemo(() => ({ update, getValues }), [update, getValues]);
78
79
 
80
+ const nobr = useContext(NobrContext);
81
+
79
82
  return (
80
83
  <LocalsUpdateContext.Provider value={updater}>
81
84
  <LocalsValuesContext.Provider value={localState}>
82
- {renderNodes(children)}
85
+ {renderNodes(children, nobr ? { nobr: true } : undefined)}
83
86
  </LocalsValuesContext.Provider>
84
87
  </LocalsUpdateContext.Provider>
85
88
  );
@@ -8,6 +8,7 @@ import {
8
8
  import {
9
9
  LocalsValuesContext,
10
10
  LocalsUpdateContext,
11
+ NobrContext,
11
12
  renderNodes,
12
13
  } from '../../markup/render';
13
14
  import { useMergedLocals } from '../../hooks/use-merged-locals';
@@ -79,6 +80,7 @@ function WidgetBody({
79
80
  parentValues: Record<string, unknown>;
80
81
  ownKeys: Record<string, unknown>;
81
82
  }) {
83
+ const nobr = useContext(NobrContext);
82
84
  const [localState, setLocalState] = useState<Record<string, unknown>>(() => ({
83
85
  ...parentValues,
84
86
  ...ownKeys,
@@ -96,7 +98,7 @@ function WidgetBody({
96
98
  return (
97
99
  <LocalsUpdateContext.Provider value={updater}>
98
100
  <LocalsValuesContext.Provider value={localState}>
99
- {renderNodes(body)}
101
+ {renderNodes(body, nobr ? { nobr: true } : undefined)}
100
102
  </LocalsValuesContext.Provider>
101
103
  </LocalsUpdateContext.Provider>
102
104
  );
@@ -108,10 +110,11 @@ export function WidgetInvocation({
108
110
  rawArgs,
109
111
  }: WidgetInvocationProps) {
110
112
  const parentValues = useContext(LocalsValuesContext);
113
+ const nobr = useContext(NobrContext);
111
114
  const [mergedVars, mergedTemps, mergedLocals] = useMergedLocals();
112
115
 
113
116
  if (params.length === 0 || !rawArgs) {
114
- return <>{renderNodes(body)}</>;
117
+ return <>{renderNodes(body, nobr ? { nobr: true } : undefined)}</>;
115
118
  }
116
119
 
117
120
  const argExprs = splitArgs(rawArgs);
@@ -13,9 +13,11 @@ import { useInterpolate } from './hooks/use-interpolate';
13
13
  import { useMergedLocals } from './hooks/use-merged-locals';
14
14
  import {
15
15
  LocalsUpdateContext,
16
- renderNodes,
16
+ NobrContext,
17
+ renderNodes as _renderNodes,
17
18
  renderInlineNodes,
18
19
  } from './markup/render';
20
+ import type { ASTNode } from './markup/ast';
19
21
  import { executeMutation } from './execute-mutation';
20
22
  import { evaluate } from './expression';
21
23
  import { useStoryStore } from './store';
@@ -56,7 +58,7 @@ export interface MacroContext {
56
58
  wrap: (content: ComponentChildren) => VNode<any>;
57
59
  useAction: (opts: UseActionOptions) => string;
58
60
  h: typeof h;
59
- renderNodes: typeof renderNodes;
61
+ renderNodes: typeof _renderNodes;
60
62
  renderInlineNodes: typeof renderInlineNodes;
61
63
  hooks: {
62
64
  useState: typeof useState;
@@ -102,6 +104,11 @@ export function defineMacro(config: MacroDefinition): void {
102
104
 
103
105
  // Always-on: cssClass + mutation
104
106
  const { update, getValues } = useContext(LocalsUpdateContext);
107
+ const nobr = useContext(NobrContext);
108
+ const renderNodes = nobr
109
+ ? (nodes: ASTNode[], options?: { nobr?: boolean }) =>
110
+ _renderNodes(nodes, { nobr: true, ...options })
111
+ : _renderNodes;
105
112
  const ctx: MacroContext = {
106
113
  collectText,
107
114
  sourceLocation: currentSourceLocation,
package/src/index.tsx CHANGED
@@ -17,7 +17,7 @@ import { buildAST } from './markup/ast';
17
17
  import { registerWidget } from './widgets/widget-registry';
18
18
  import type { ASTNode } from './markup/ast';
19
19
  import './macros/register-builtins';
20
- import './styles.css';
20
+ import builtinCSS from './styles.css?inline';
21
21
 
22
22
  function renderErrors(root: HTMLElement, errors: string[]) {
23
23
  root.innerHTML = '';
@@ -42,6 +42,12 @@ function renderErrors(root: HTMLElement, errors: string[]) {
42
42
  function boot() {
43
43
  const storyData = parseStoryData();
44
44
 
45
+ // Inject built-in styles with an id so they can be disabled at runtime
46
+ const builtinStyle = document.createElement('style');
47
+ builtinStyle.id = 'spindle-styles';
48
+ builtinStyle.textContent = builtinCSS;
49
+ document.head.appendChild(builtinStyle);
50
+
45
51
  // Install Story API before author script runs
46
52
  installStoryAPI();
47
53
 
package/src/store.ts CHANGED
@@ -205,6 +205,7 @@ export interface StoryState {
205
205
  loadError: string | null;
206
206
  transitionConfig: TransitionConfig | null;
207
207
  nextTransition: TransitionConfig | null;
208
+ nobr: boolean;
208
209
 
209
210
  setMaxHistory: (limit: number) => void;
210
211
  init: (
@@ -249,6 +250,7 @@ export const useStoryStore = create<StoryState>()(
249
250
  loadError: null,
250
251
  transitionConfig: null,
251
252
  nextTransition: null,
253
+ nobr: false,
252
254
 
253
255
  setMaxHistory: (limit: number) => {
254
256
  set((state) => {
package/src/story-api.ts CHANGED
@@ -73,6 +73,8 @@ export interface StoryAPI {
73
73
  callbackOrOptions: (() => void) | WatchOptions,
74
74
  ): () => void;
75
75
  unwatch(name: string): void;
76
+ setNobr(enabled: boolean): void;
77
+ setCSS(enabled: boolean): void;
76
78
  setTransition(config: TransitionConfig | null): void;
77
79
  setNextTransition(config: TransitionConfig | null): void;
78
80
  random(): number;
@@ -284,6 +286,15 @@ function createStoryAPI(): StoryAPI {
284
286
  removeTrigger(name);
285
287
  },
286
288
 
289
+ setNobr(enabled: boolean): void {
290
+ useStoryStore.setState({ nobr: enabled });
291
+ },
292
+
293
+ setCSS(enabled: boolean): void {
294
+ const el = document.getElementById('spindle-styles');
295
+ if (el) (el as HTMLStyleElement).disabled = !enabled;
296
+ },
297
+
287
298
  setTransition(config: TransitionConfig | null): void {
288
299
  useStoryStore.getState().setTransition(config);
289
300
  },
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />