@rohal12/spindle 0.15.0 → 0.16.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.
- package/dist/pkg/format.js +1 -1
- package/package.json +1 -1
- package/src/components/macros/Back.tsx +5 -6
- package/src/components/macros/Button.tsx +5 -9
- package/src/components/macros/Checkbox.tsx +5 -7
- package/src/components/macros/Computed.tsx +5 -5
- package/src/components/macros/Cycle.tsx +5 -9
- package/src/components/macros/Do.tsx +5 -6
- package/src/components/macros/For.tsx +5 -8
- package/src/components/macros/Forward.tsx +5 -6
- package/src/components/macros/Goto.tsx +5 -5
- package/src/components/macros/If.tsx +5 -5
- package/src/components/macros/Include.tsx +5 -7
- package/src/components/macros/Listbox.tsx +6 -9
- package/src/components/macros/MacroLink.tsx +6 -9
- package/src/components/macros/Meter.tsx +5 -7
- package/src/components/macros/Numberbox.tsx +5 -7
- package/src/components/macros/PassageDisplay.tsx +5 -6
- package/src/components/macros/Print.tsx +5 -7
- package/src/components/macros/QuickLoad.tsx +5 -6
- package/src/components/macros/QuickSave.tsx +5 -6
- package/src/components/macros/Radiobutton.tsx +5 -7
- package/src/components/macros/Repeat.tsx +6 -10
- package/src/components/macros/Restart.tsx +5 -6
- package/src/components/macros/Saves.tsx +5 -6
- package/src/components/macros/Set.tsx +5 -5
- package/src/components/macros/SettingsButton.tsx +5 -6
- package/src/components/macros/Stop.tsx +5 -1
- package/src/components/macros/StoryTitle.tsx +5 -6
- package/src/components/macros/Switch.tsx +7 -6
- package/src/components/macros/Textarea.tsx +5 -7
- package/src/components/macros/Textbox.tsx +5 -7
- package/src/components/macros/Timed.tsx +22 -32
- package/src/components/macros/Type.tsx +5 -9
- package/src/components/macros/Unset.tsx +5 -5
- package/src/components/macros/Widget.tsx +5 -7
- package/src/index.tsx +1 -0
- package/src/macros/register-builtins.ts +35 -0
- package/src/markup/render.tsx +36 -404
- package/src/registry.ts +13 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { useLayoutEffect, useContext } from 'preact/hooks';
|
|
2
2
|
import { RepeatContext } from './Repeat';
|
|
3
|
+
import { registerMacro } from '../../registry';
|
|
4
|
+
import type { MacroProps } from '../../registry';
|
|
3
5
|
|
|
4
|
-
export function Stop() {
|
|
6
|
+
export function Stop(_props: MacroProps) {
|
|
5
7
|
const { stop } = useContext(RepeatContext);
|
|
6
8
|
|
|
7
9
|
useLayoutEffect(() => {
|
|
@@ -10,3 +12,5 @@ export function Stop() {
|
|
|
10
12
|
|
|
11
13
|
return null;
|
|
12
14
|
}
|
|
15
|
+
|
|
16
|
+
registerMacro('stop', Stop);
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { useStoryStore } from '../../store';
|
|
2
|
+
import { registerMacro } from '../../registry';
|
|
3
|
+
import type { MacroProps } from '../../registry';
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
className?: string;
|
|
5
|
-
id?: string;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function StoryTitle({ className, id }: StoryTitleProps) {
|
|
5
|
+
export function StoryTitle({ className, id }: MacroProps) {
|
|
9
6
|
const name = useStoryStore((s) => s.storyData?.name || '');
|
|
10
7
|
const cls = className ? `story-title ${className}` : 'story-title';
|
|
11
8
|
|
|
@@ -18,3 +15,5 @@ export function StoryTitle({ className, id }: StoryTitleProps) {
|
|
|
18
15
|
</span>
|
|
19
16
|
);
|
|
20
17
|
}
|
|
18
|
+
|
|
19
|
+
registerMacro('story-title', StoryTitle);
|
|
@@ -2,14 +2,11 @@ import { evaluate } from '../../expression';
|
|
|
2
2
|
import { renderNodes } from '../../markup/render';
|
|
3
3
|
import { useMergedLocals } from '../../hooks/use-merged-locals';
|
|
4
4
|
import { currentSourceLocation } from '../../utils/source-location';
|
|
5
|
+
import { registerMacro, registerSubMacro } from '../../registry';
|
|
6
|
+
import type { MacroProps } from '../../registry';
|
|
5
7
|
import type { Branch } from '../../markup/ast';
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
rawArgs: string;
|
|
9
|
-
branches: Branch[];
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function Switch({ rawArgs, branches }: SwitchProps) {
|
|
9
|
+
export function Switch({ rawArgs, branches = [] }: MacroProps) {
|
|
13
10
|
const [mergedVars, mergedTemps, mergedLocals] = useMergedLocals();
|
|
14
11
|
|
|
15
12
|
let switchValue: unknown;
|
|
@@ -65,3 +62,7 @@ export function Switch({ rawArgs, branches }: SwitchProps) {
|
|
|
65
62
|
|
|
66
63
|
return null;
|
|
67
64
|
}
|
|
65
|
+
|
|
66
|
+
registerMacro('switch', Switch);
|
|
67
|
+
registerSubMacro('case');
|
|
68
|
+
registerSubMacro('default');
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { useStoryStore } from '../../store';
|
|
2
2
|
import { useAction } from '../../hooks/use-action';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
rawArgs: string;
|
|
6
|
-
className?: string;
|
|
7
|
-
id?: string;
|
|
8
|
-
}
|
|
3
|
+
import { registerMacro } from '../../registry';
|
|
4
|
+
import type { MacroProps } from '../../registry';
|
|
9
5
|
|
|
10
6
|
function parseArgs(rawArgs: string): { varName: string; placeholder: string } {
|
|
11
7
|
const match = rawArgs.match(/^\s*(["']?\$\w+["']?)\s*(?:["'](.*)["'])?\s*$/);
|
|
@@ -17,7 +13,7 @@ function parseArgs(rawArgs: string): { varName: string; placeholder: string } {
|
|
|
17
13
|
return { varName, placeholder };
|
|
18
14
|
}
|
|
19
15
|
|
|
20
|
-
export function Textarea({ rawArgs, className, id }:
|
|
16
|
+
export function Textarea({ rawArgs, className, id }: MacroProps) {
|
|
21
17
|
const { varName, placeholder } = parseArgs(rawArgs);
|
|
22
18
|
const name = varName.startsWith('$') ? varName.slice(1) : varName;
|
|
23
19
|
|
|
@@ -48,3 +44,5 @@ export function Textarea({ rawArgs, className, id }: TextareaProps) {
|
|
|
48
44
|
/>
|
|
49
45
|
);
|
|
50
46
|
}
|
|
47
|
+
|
|
48
|
+
registerMacro('textarea', Textarea);
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { useStoryStore } from '../../store';
|
|
2
2
|
import { useAction } from '../../hooks/use-action';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
rawArgs: string;
|
|
6
|
-
className?: string;
|
|
7
|
-
id?: string;
|
|
8
|
-
}
|
|
3
|
+
import { registerMacro } from '../../registry';
|
|
4
|
+
import type { MacroProps } from '../../registry';
|
|
9
5
|
|
|
10
6
|
function parseArgs(rawArgs: string): { varName: string; placeholder: string } {
|
|
11
7
|
const match = rawArgs.match(/^\s*(["']?\$\w+["']?)\s*(?:["'](.*)["'])?\s*$/);
|
|
@@ -17,7 +13,7 @@ function parseArgs(rawArgs: string): { varName: string; placeholder: string } {
|
|
|
17
13
|
return { varName, placeholder };
|
|
18
14
|
}
|
|
19
15
|
|
|
20
|
-
export function Textbox({ rawArgs, className, id }:
|
|
16
|
+
export function Textbox({ rawArgs, className, id }: MacroProps) {
|
|
21
17
|
const { varName, placeholder } = parseArgs(rawArgs);
|
|
22
18
|
const name = varName.startsWith('$') ? varName.slice(1) : varName;
|
|
23
19
|
|
|
@@ -47,3 +43,5 @@ export function Textbox({ rawArgs, className, id }: TextboxProps) {
|
|
|
47
43
|
/>
|
|
48
44
|
);
|
|
49
45
|
}
|
|
46
|
+
|
|
47
|
+
registerMacro('textbox', Textbox);
|
|
@@ -2,37 +2,21 @@ import { useState, useEffect, useMemo } from 'preact/hooks';
|
|
|
2
2
|
import { renderNodes } from '../../markup/render';
|
|
3
3
|
import { parseDelay } from '../../utils/parse-delay';
|
|
4
4
|
import { useInterpolate } from '../../hooks/use-interpolate';
|
|
5
|
-
import
|
|
5
|
+
import { registerMacro, registerSubMacro } from '../../registry';
|
|
6
|
+
import type { MacroProps } from '../../registry';
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
rawArgs: string;
|
|
9
|
-
children: ASTNode[];
|
|
10
|
-
branches: Branch[];
|
|
11
|
-
className?: string;
|
|
12
|
-
id?: string;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function Timed({
|
|
16
|
-
rawArgs,
|
|
17
|
-
children,
|
|
18
|
-
branches,
|
|
19
|
-
className,
|
|
20
|
-
id,
|
|
21
|
-
}: TimedProps) {
|
|
8
|
+
export function Timed({ branches = [] }: MacroProps) {
|
|
22
9
|
const resolve = useInterpolate();
|
|
23
|
-
className
|
|
24
|
-
id
|
|
25
|
-
// Section 0 = initial children, sections 1..N = {next} branches
|
|
26
|
-
// Each section has its own delay
|
|
10
|
+
// For branching blocks, className/id from the opening tag goes on branches[0],
|
|
11
|
+
// so the component-level className/id is unused. Each branch carries its own.
|
|
27
12
|
const sections = useMemo(() => {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
}, [rawArgs, children, branches]);
|
|
13
|
+
return branches.map((branch) => ({
|
|
14
|
+
delay: branch.rawArgs ? parseDelay(branch.rawArgs) : 0,
|
|
15
|
+
nodes: branch.children,
|
|
16
|
+
className: branch.className,
|
|
17
|
+
id: branch.id,
|
|
18
|
+
}));
|
|
19
|
+
}, [branches]);
|
|
36
20
|
|
|
37
21
|
const [visibleIndex, setVisibleIndex] = useState(-1);
|
|
38
22
|
|
|
@@ -51,16 +35,22 @@ export function Timed({
|
|
|
51
35
|
|
|
52
36
|
if (visibleIndex < 0) return null;
|
|
53
37
|
|
|
54
|
-
const
|
|
38
|
+
const section = sections[visibleIndex]!;
|
|
39
|
+
const content = renderNodes(section.nodes);
|
|
40
|
+
const sectionClass = resolve(section.className);
|
|
41
|
+
const sectionId = resolve(section.id);
|
|
55
42
|
|
|
56
|
-
if (
|
|
43
|
+
if (sectionClass || sectionId)
|
|
57
44
|
return (
|
|
58
45
|
<span
|
|
59
|
-
id={
|
|
60
|
-
class={
|
|
46
|
+
id={sectionId}
|
|
47
|
+
class={sectionClass}
|
|
61
48
|
>
|
|
62
49
|
{content}
|
|
63
50
|
</span>
|
|
64
51
|
);
|
|
65
52
|
return <>{content}</>;
|
|
66
53
|
}
|
|
54
|
+
|
|
55
|
+
registerMacro('timed', Timed);
|
|
56
|
+
registerSubMacro('next');
|
|
@@ -2,16 +2,10 @@ import { useState, useEffect, useRef } from 'preact/hooks';
|
|
|
2
2
|
import { renderInlineNodes } from '../../markup/render';
|
|
3
3
|
import { parseDelay } from '../../utils/parse-delay';
|
|
4
4
|
import { useInterpolate } from '../../hooks/use-interpolate';
|
|
5
|
-
import
|
|
5
|
+
import { registerMacro } from '../../registry';
|
|
6
|
+
import type { MacroProps } from '../../registry';
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
rawArgs: string;
|
|
9
|
-
children: ASTNode[];
|
|
10
|
-
className?: string;
|
|
11
|
-
id?: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function Type({ rawArgs, children, className, id }: TypeProps) {
|
|
8
|
+
export function Type({ rawArgs, children = [], className, id }: MacroProps) {
|
|
15
9
|
const resolve = useInterpolate();
|
|
16
10
|
className = resolve(className);
|
|
17
11
|
id = resolve(id);
|
|
@@ -78,3 +72,5 @@ export function Type({ rawArgs, children, className, id }: TypeProps) {
|
|
|
78
72
|
</span>
|
|
79
73
|
);
|
|
80
74
|
}
|
|
75
|
+
|
|
76
|
+
registerMacro('type', Type);
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { useRef } from 'preact/hooks';
|
|
2
2
|
import { useStoryStore } from '../../store';
|
|
3
|
+
import { registerMacro } from '../../registry';
|
|
4
|
+
import type { MacroProps } from '../../registry';
|
|
3
5
|
|
|
4
|
-
|
|
5
|
-
rawArgs: string;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function Unset({ rawArgs }: UnsetProps) {
|
|
6
|
+
export function Unset({ rawArgs }: MacroProps) {
|
|
9
7
|
const ran = useRef(false);
|
|
10
8
|
|
|
11
9
|
if (!ran.current) {
|
|
@@ -26,3 +24,5 @@ export function Unset({ rawArgs }: UnsetProps) {
|
|
|
26
24
|
|
|
27
25
|
return null;
|
|
28
26
|
}
|
|
27
|
+
|
|
28
|
+
registerMacro('unset', Unset);
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { useLayoutEffect } from 'preact/hooks';
|
|
2
2
|
import { registerWidget } from '../../widgets/widget-registry';
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
interface WidgetProps {
|
|
6
|
-
rawArgs: string;
|
|
7
|
-
children: ASTNode[];
|
|
8
|
-
}
|
|
3
|
+
import { registerMacro } from '../../registry';
|
|
4
|
+
import type { MacroProps } from '../../registry';
|
|
9
5
|
|
|
10
6
|
/**
|
|
11
7
|
* Parse widget definition args: "WidgetName" or "WidgetName" $param1 $param2
|
|
@@ -17,7 +13,7 @@ function parseWidgetDef(rawArgs: string): { name: string; params: string[] } {
|
|
|
17
13
|
return { name, params };
|
|
18
14
|
}
|
|
19
15
|
|
|
20
|
-
export function Widget({ rawArgs, children }:
|
|
16
|
+
export function Widget({ rawArgs, children = [] }: MacroProps) {
|
|
21
17
|
const { name, params } = parseWidgetDef(rawArgs);
|
|
22
18
|
|
|
23
19
|
useLayoutEffect(() => {
|
|
@@ -26,3 +22,5 @@ export function Widget({ rawArgs, children }: WidgetProps) {
|
|
|
26
22
|
|
|
27
23
|
return null;
|
|
28
24
|
}
|
|
25
|
+
|
|
26
|
+
registerMacro('widget', Widget);
|
package/src/index.tsx
CHANGED
|
@@ -14,6 +14,7 @@ import { tokenize } from './markup/tokenizer';
|
|
|
14
14
|
import { buildAST } from './markup/ast';
|
|
15
15
|
import { registerWidget } from './widgets/widget-registry';
|
|
16
16
|
import type { ASTNode } from './markup/ast';
|
|
17
|
+
import './macros/register-builtins';
|
|
17
18
|
import './styles.css';
|
|
18
19
|
|
|
19
20
|
function renderErrors(root: HTMLElement, errors: string[]) {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Import all built-in macro components to trigger their self-registration.
|
|
2
|
+
import '../components/macros/Set';
|
|
3
|
+
import '../components/macros/Print';
|
|
4
|
+
import '../components/macros/Computed';
|
|
5
|
+
import '../components/macros/Meter';
|
|
6
|
+
import '../components/macros/If';
|
|
7
|
+
import '../components/macros/For';
|
|
8
|
+
import '../components/macros/Do';
|
|
9
|
+
import '../components/macros/Button';
|
|
10
|
+
import '../components/macros/MacroLink';
|
|
11
|
+
import '../components/macros/Switch';
|
|
12
|
+
import '../components/macros/Timed';
|
|
13
|
+
import '../components/macros/Repeat';
|
|
14
|
+
import '../components/macros/Stop';
|
|
15
|
+
import '../components/macros/Type';
|
|
16
|
+
import '../components/macros/Widget';
|
|
17
|
+
import '../components/macros/StoryTitle';
|
|
18
|
+
import '../components/macros/Back';
|
|
19
|
+
import '../components/macros/Forward';
|
|
20
|
+
import '../components/macros/Restart';
|
|
21
|
+
import '../components/macros/QuickSave';
|
|
22
|
+
import '../components/macros/QuickLoad';
|
|
23
|
+
import '../components/macros/SettingsButton';
|
|
24
|
+
import '../components/macros/Saves';
|
|
25
|
+
import '../components/macros/Include';
|
|
26
|
+
import '../components/macros/Goto';
|
|
27
|
+
import '../components/macros/Unset';
|
|
28
|
+
import '../components/macros/Textbox';
|
|
29
|
+
import '../components/macros/Numberbox';
|
|
30
|
+
import '../components/macros/Textarea';
|
|
31
|
+
import '../components/macros/Checkbox';
|
|
32
|
+
import '../components/macros/Radiobutton';
|
|
33
|
+
import '../components/macros/Listbox';
|
|
34
|
+
import '../components/macros/Cycle';
|
|
35
|
+
import '../components/macros/PassageDisplay';
|