@magicborn/dialogue-forge 0.1.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/README.md +233 -0
- package/bin/dialogue-forge.js +78 -0
- package/demo/app/layout.tsx +36 -0
- package/demo/app/page.tsx +440 -0
- package/demo/components/ThemeSwitcher.tsx +611 -0
- package/demo/next.config.mjs +7 -0
- package/demo/package.json +29 -0
- package/demo/postcss.config.mjs +7 -0
- package/demo/public/logo.svg +1 -0
- package/demo/styles/globals.css +19 -0
- package/demo/tailwind.config.ts +90 -0
- package/demo/tsconfig.json +42 -0
- package/dist/components/ChoiceEdgeV2.d.ts +3 -0
- package/dist/components/ChoiceEdgeV2.js +103 -0
- package/dist/components/CodeBlock.d.ts +8 -0
- package/dist/components/CodeBlock.js +24 -0
- package/dist/components/ConditionAutocomplete.d.ts +14 -0
- package/dist/components/ConditionAutocomplete.js +284 -0
- package/dist/components/ConditionalNodeV2.d.ts +16 -0
- package/dist/components/ConditionalNodeV2.js +147 -0
- package/dist/components/DialogueEditorV2.d.ts +22 -0
- package/dist/components/DialogueEditorV2.js +1170 -0
- package/dist/components/EdgeIcon.d.ts +8 -0
- package/dist/components/EdgeIcon.js +13 -0
- package/dist/components/ExampleLoader.d.ts +11 -0
- package/dist/components/ExampleLoader.js +52 -0
- package/dist/components/ExampleLoaderButton.d.ts +15 -0
- package/dist/components/ExampleLoaderButton.js +102 -0
- package/dist/components/FlagManager.d.ts +11 -0
- package/dist/components/FlagManager.js +282 -0
- package/dist/components/FlagSelector.d.ts +11 -0
- package/dist/components/FlagSelector.js +235 -0
- package/dist/components/GuidePanel.d.ts +7 -0
- package/dist/components/GuidePanel.js +1176 -0
- package/dist/components/Minimap.d.ts +16 -0
- package/dist/components/Minimap.js +93 -0
- package/dist/components/NPCEdgeV2.d.ts +3 -0
- package/dist/components/NPCEdgeV2.js +104 -0
- package/dist/components/NPCNodeV2.d.ts +26 -0
- package/dist/components/NPCNodeV2.js +86 -0
- package/dist/components/NodeEditor.d.ts +18 -0
- package/dist/components/NodeEditor.js +1025 -0
- package/dist/components/PlayView.d.ts +12 -0
- package/dist/components/PlayView.js +307 -0
- package/dist/components/PlayerNodeV2.d.ts +16 -0
- package/dist/components/PlayerNodeV2.js +139 -0
- package/dist/components/ReactFlowPOC.d.ts +61 -0
- package/dist/components/ReactFlowPOC.js +312 -0
- package/dist/components/ScenePlayer.d.ts +18 -0
- package/dist/components/ScenePlayer.js +196 -0
- package/dist/components/YarnView.d.ts +9 -0
- package/dist/components/YarnView.js +45 -0
- package/dist/components/ZoomControls.d.ts +11 -0
- package/dist/components/ZoomControls.js +34 -0
- package/dist/esm/components/ChoiceEdgeV2.d.ts +3 -0
- package/dist/esm/components/ChoiceEdgeV2.js +67 -0
- package/dist/esm/components/CodeBlock.d.ts +8 -0
- package/dist/esm/components/CodeBlock.js +18 -0
- package/dist/esm/components/ConditionAutocomplete.d.ts +14 -0
- package/dist/esm/components/ConditionAutocomplete.js +248 -0
- package/dist/esm/components/ConditionalNodeV2.d.ts +16 -0
- package/dist/esm/components/ConditionalNodeV2.js +111 -0
- package/dist/esm/components/DialogueEditorV2.d.ts +22 -0
- package/dist/esm/components/DialogueEditorV2.js +1134 -0
- package/dist/esm/components/EdgeIcon.d.ts +8 -0
- package/dist/esm/components/EdgeIcon.js +7 -0
- package/dist/esm/components/ExampleLoader.d.ts +11 -0
- package/dist/esm/components/ExampleLoader.js +46 -0
- package/dist/esm/components/ExampleLoaderButton.d.ts +15 -0
- package/dist/esm/components/ExampleLoaderButton.js +66 -0
- package/dist/esm/components/FlagManager.d.ts +11 -0
- package/dist/esm/components/FlagManager.js +246 -0
- package/dist/esm/components/FlagSelector.d.ts +11 -0
- package/dist/esm/components/FlagSelector.js +199 -0
- package/dist/esm/components/GuidePanel.d.ts +7 -0
- package/dist/esm/components/GuidePanel.js +1140 -0
- package/dist/esm/components/Minimap.d.ts +16 -0
- package/dist/esm/components/Minimap.js +57 -0
- package/dist/esm/components/NPCEdgeV2.d.ts +3 -0
- package/dist/esm/components/NPCEdgeV2.js +68 -0
- package/dist/esm/components/NPCNodeV2.d.ts +26 -0
- package/dist/esm/components/NPCNodeV2.js +80 -0
- package/dist/esm/components/NodeEditor.d.ts +18 -0
- package/dist/esm/components/NodeEditor.js +989 -0
- package/dist/esm/components/PlayView.d.ts +12 -0
- package/dist/esm/components/PlayView.js +271 -0
- package/dist/esm/components/PlayerNodeV2.d.ts +16 -0
- package/dist/esm/components/PlayerNodeV2.js +103 -0
- package/dist/esm/components/ReactFlowPOC.d.ts +61 -0
- package/dist/esm/components/ReactFlowPOC.js +275 -0
- package/dist/esm/components/ScenePlayer.d.ts +18 -0
- package/dist/esm/components/ScenePlayer.js +160 -0
- package/dist/esm/components/YarnView.d.ts +9 -0
- package/dist/esm/components/YarnView.js +39 -0
- package/dist/esm/components/ZoomControls.d.ts +11 -0
- package/dist/esm/components/ZoomControls.js +28 -0
- package/dist/esm/examples/example-loader.d.ts +29 -0
- package/dist/esm/examples/example-loader.js +103 -0
- package/dist/esm/examples/examples-registry.d.ts +38 -0
- package/dist/esm/examples/examples-registry.js +153 -0
- package/dist/esm/examples/index.d.ts +26 -0
- package/dist/esm/examples/index.js +50 -0
- package/dist/esm/examples/legacy-examples.d.ts +9 -0
- package/dist/esm/examples/legacy-examples.js +814 -0
- package/dist/esm/examples/yarn-examples.d.ts +35 -0
- package/dist/esm/examples/yarn-examples.js +181 -0
- package/dist/esm/index.d.ts +21 -0
- package/dist/esm/index.js +26 -0
- package/dist/esm/lib/flag-manager.d.ts +21 -0
- package/dist/esm/lib/flag-manager.js +93 -0
- package/dist/esm/lib/yarn-converter/__tests__/round-trip.test.d.ts +1 -0
- package/dist/esm/lib/yarn-converter/__tests__/round-trip.test.js +169 -0
- package/dist/esm/lib/yarn-converter.d.ts +17 -0
- package/dist/esm/lib/yarn-converter.js +521 -0
- package/dist/esm/lib/yarn-runner/__tests__/condition-evaluator.test.d.ts +1 -0
- package/dist/esm/lib/yarn-runner/__tests__/condition-evaluator.test.js +171 -0
- package/dist/esm/lib/yarn-runner/__tests__/node-processor.test.d.ts +1 -0
- package/dist/esm/lib/yarn-runner/__tests__/node-processor.test.js +237 -0
- package/dist/esm/lib/yarn-runner/__tests__/variable-manager.test.d.ts +1 -0
- package/dist/esm/lib/yarn-runner/__tests__/variable-manager.test.js +106 -0
- package/dist/esm/lib/yarn-runner/condition-evaluator.d.ts +12 -0
- package/dist/esm/lib/yarn-runner/condition-evaluator.js +56 -0
- package/dist/esm/lib/yarn-runner/index.d.ts +12 -0
- package/dist/esm/lib/yarn-runner/index.js +11 -0
- package/dist/esm/lib/yarn-runner/node-processor.d.ts +18 -0
- package/dist/esm/lib/yarn-runner/node-processor.js +129 -0
- package/dist/esm/lib/yarn-runner/variable-manager.d.ts +51 -0
- package/dist/esm/lib/yarn-runner/variable-manager.js +120 -0
- package/dist/esm/lib/yarn-runner/variable-operations.d.ts +16 -0
- package/dist/esm/lib/yarn-runner/variable-operations.js +88 -0
- package/dist/esm/types/conditionals.d.ts +29 -0
- package/dist/esm/types/conditionals.js +1 -0
- package/dist/esm/types/constants.d.ts +59 -0
- package/dist/esm/types/constants.js +55 -0
- package/dist/esm/types/flags.d.ts +49 -0
- package/dist/esm/types/flags.js +49 -0
- package/dist/esm/types/game-state.d.ts +62 -0
- package/dist/esm/types/game-state.js +6 -0
- package/dist/esm/types/index.d.ts +77 -0
- package/dist/esm/types/index.js +1 -0
- package/dist/esm/utils/constants.d.ts +5 -0
- package/dist/esm/utils/constants.js +5 -0
- package/dist/esm/utils/feature-flags.d.ts +11 -0
- package/dist/esm/utils/feature-flags.js +11 -0
- package/dist/esm/utils/game-state-flattener.d.ts +41 -0
- package/dist/esm/utils/game-state-flattener.js +135 -0
- package/dist/esm/utils/layout/collision.d.ts +27 -0
- package/dist/esm/utils/layout/collision.js +74 -0
- package/dist/esm/utils/layout/index.d.ts +82 -0
- package/dist/esm/utils/layout/index.js +98 -0
- package/dist/esm/utils/layout/registry.d.ts +91 -0
- package/dist/esm/utils/layout/registry.js +148 -0
- package/dist/esm/utils/layout/strategies/dagre.d.ts +19 -0
- package/dist/esm/utils/layout/strategies/dagre.js +182 -0
- package/dist/esm/utils/layout/strategies/force.d.ts +21 -0
- package/dist/esm/utils/layout/strategies/force.js +178 -0
- package/dist/esm/utils/layout/strategies/grid.d.ts +17 -0
- package/dist/esm/utils/layout/strategies/grid.js +91 -0
- package/dist/esm/utils/layout/strategies/index.d.ts +8 -0
- package/dist/esm/utils/layout/strategies/index.js +8 -0
- package/dist/esm/utils/layout/types.d.ts +100 -0
- package/dist/esm/utils/layout/types.js +7 -0
- package/dist/esm/utils/layout.d.ts +9 -0
- package/dist/esm/utils/layout.js +17 -0
- package/dist/esm/utils/node-helpers.d.ts +7 -0
- package/dist/esm/utils/node-helpers.js +94 -0
- package/dist/esm/utils/reactflow-converter.d.ts +42 -0
- package/dist/esm/utils/reactflow-converter.js +217 -0
- package/dist/examples/example-loader.d.ts +29 -0
- package/dist/examples/example-loader.js +109 -0
- package/dist/examples/examples-registry.d.ts +38 -0
- package/dist/examples/examples-registry.js +160 -0
- package/dist/examples/index.d.ts +26 -0
- package/dist/examples/index.js +63 -0
- package/dist/examples/legacy-examples.d.ts +9 -0
- package/dist/examples/legacy-examples.js +817 -0
- package/dist/examples/yarn-examples.d.ts +35 -0
- package/dist/examples/yarn-examples.js +189 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +66 -0
- package/dist/lib/flag-manager.d.ts +21 -0
- package/dist/lib/flag-manager.js +99 -0
- package/dist/lib/yarn-converter/__tests__/round-trip.test.d.ts +1 -0
- package/dist/lib/yarn-converter/__tests__/round-trip.test.js +171 -0
- package/dist/lib/yarn-converter.d.ts +17 -0
- package/dist/lib/yarn-converter.js +525 -0
- package/dist/lib/yarn-runner/__tests__/condition-evaluator.test.d.ts +1 -0
- package/dist/lib/yarn-runner/__tests__/condition-evaluator.test.js +173 -0
- package/dist/lib/yarn-runner/__tests__/node-processor.test.d.ts +1 -0
- package/dist/lib/yarn-runner/__tests__/node-processor.test.js +239 -0
- package/dist/lib/yarn-runner/__tests__/variable-manager.test.d.ts +1 -0
- package/dist/lib/yarn-runner/__tests__/variable-manager.test.js +108 -0
- package/dist/lib/yarn-runner/condition-evaluator.d.ts +12 -0
- package/dist/lib/yarn-runner/condition-evaluator.js +60 -0
- package/dist/lib/yarn-runner/index.d.ts +12 -0
- package/dist/lib/yarn-runner/index.js +21 -0
- package/dist/lib/yarn-runner/node-processor.d.ts +18 -0
- package/dist/lib/yarn-runner/node-processor.js +133 -0
- package/dist/lib/yarn-runner/variable-manager.d.ts +51 -0
- package/dist/lib/yarn-runner/variable-manager.js +124 -0
- package/dist/lib/yarn-runner/variable-operations.d.ts +16 -0
- package/dist/lib/yarn-runner/variable-operations.js +92 -0
- package/dist/types/conditionals.d.ts +29 -0
- package/dist/types/conditionals.js +2 -0
- package/dist/types/constants.d.ts +59 -0
- package/dist/types/constants.js +58 -0
- package/dist/types/flags.d.ts +49 -0
- package/dist/types/flags.js +52 -0
- package/dist/types/game-state.d.ts +62 -0
- package/dist/types/game-state.js +7 -0
- package/dist/types/index.d.ts +77 -0
- package/dist/types/index.js +2 -0
- package/dist/utils/constants.d.ts +5 -0
- package/dist/utils/constants.js +8 -0
- package/dist/utils/feature-flags.d.ts +11 -0
- package/dist/utils/feature-flags.js +14 -0
- package/dist/utils/game-state-flattener.d.ts +41 -0
- package/dist/utils/game-state-flattener.js +140 -0
- package/dist/utils/layout/collision.d.ts +27 -0
- package/dist/utils/layout/collision.js +77 -0
- package/dist/utils/layout/index.d.ts +82 -0
- package/dist/utils/layout/index.js +109 -0
- package/dist/utils/layout/registry.d.ts +91 -0
- package/dist/utils/layout/registry.js +151 -0
- package/dist/utils/layout/strategies/dagre.d.ts +19 -0
- package/dist/utils/layout/strategies/dagre.js +189 -0
- package/dist/utils/layout/strategies/force.d.ts +21 -0
- package/dist/utils/layout/strategies/force.js +182 -0
- package/dist/utils/layout/strategies/grid.d.ts +17 -0
- package/dist/utils/layout/strategies/grid.js +95 -0
- package/dist/utils/layout/strategies/index.d.ts +8 -0
- package/dist/utils/layout/strategies/index.js +14 -0
- package/dist/utils/layout/types.d.ts +100 -0
- package/dist/utils/layout/types.js +8 -0
- package/dist/utils/layout.d.ts +9 -0
- package/dist/utils/layout.js +25 -0
- package/dist/utils/node-helpers.d.ts +7 -0
- package/dist/utils/node-helpers.js +101 -0
- package/dist/utils/reactflow-converter.d.ts +42 -0
- package/dist/utils/reactflow-converter.js +223 -0
- package/package.json +70 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.EdgeIcon = EdgeIcon;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
function EdgeIcon({ color = 'currentColor', size = 24, className = '' }) {
|
|
9
|
+
return (react_1.default.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: className },
|
|
10
|
+
react_1.default.createElement("circle", { cx: "6", cy: "12", r: "2", fill: color }),
|
|
11
|
+
react_1.default.createElement("circle", { cx: "18", cy: "12", r: "2", fill: color }),
|
|
12
|
+
react_1.default.createElement("line", { x1: "8", y1: "12", x2: "16", y2: "12", stroke: color, strokeWidth: "2" })));
|
|
13
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { DialogueTree } from '../types';
|
|
3
|
+
import { FlagSchema } from '../types/flags';
|
|
4
|
+
interface ExampleLoaderProps {
|
|
5
|
+
onLoadDialogue: (dialogue: DialogueTree) => void;
|
|
6
|
+
onLoadFlags: (flags: FlagSchema) => void;
|
|
7
|
+
currentDialogue?: DialogueTree;
|
|
8
|
+
currentFlags?: FlagSchema;
|
|
9
|
+
}
|
|
10
|
+
export declare function ExampleLoader({ onLoadDialogue, onLoadFlags }: ExampleLoaderProps): React.JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ExampleLoader = ExampleLoader;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const examples_1 = require("../examples");
|
|
9
|
+
function ExampleLoader({ onLoadDialogue, onLoadFlags }) {
|
|
10
|
+
const handleDialogueChange = (e) => {
|
|
11
|
+
const name = e.target.value;
|
|
12
|
+
if (name) {
|
|
13
|
+
const dialogue = (0, examples_1.getExampleDialogue)(name);
|
|
14
|
+
if (dialogue) {
|
|
15
|
+
onLoadDialogue(dialogue);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
const handleFlagsChange = (e) => {
|
|
20
|
+
const name = e.target.value;
|
|
21
|
+
if (name) {
|
|
22
|
+
const flags = (0, examples_1.getDemoFlagSchema)(name);
|
|
23
|
+
if (flags) {
|
|
24
|
+
onLoadFlags(flags);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
return (react_1.default.createElement("div", { className: "flex items-center gap-3" },
|
|
29
|
+
react_1.default.createElement("select", { onChange: handleDialogueChange, defaultValue: "", className: "bg-[#12121a] border border-[#2a2a3e] text-white text-sm px-3 py-1.5 rounded hover:border-[#3a3a4e] focus:outline-none focus:border-[#e94560] cursor-pointer", title: "Load Dialogue Example" },
|
|
30
|
+
react_1.default.createElement("option", { value: "", disabled: true }, "Dialogue Example..."),
|
|
31
|
+
(0, examples_1.listExamples)().map(name => {
|
|
32
|
+
const dialogue = (0, examples_1.getExampleDialogue)(name);
|
|
33
|
+
if (!dialogue)
|
|
34
|
+
return null;
|
|
35
|
+
const nodeCount = Object.keys(dialogue.nodes).length;
|
|
36
|
+
return (react_1.default.createElement("option", { key: name, value: name },
|
|
37
|
+
dialogue.title,
|
|
38
|
+
" (",
|
|
39
|
+
nodeCount,
|
|
40
|
+
" nodes)"));
|
|
41
|
+
}).filter(Boolean)),
|
|
42
|
+
react_1.default.createElement("select", { onChange: handleFlagsChange, defaultValue: "", className: "bg-[#12121a] border border-[#2a2a3e] text-white text-sm px-3 py-1.5 rounded hover:border-[#3a3a4e] focus:outline-none focus:border-[#e94560] cursor-pointer", title: "Load Flag Schema" },
|
|
43
|
+
react_1.default.createElement("option", { value: "", disabled: true }, "Flag Schema..."),
|
|
44
|
+
(0, examples_1.listDemoFlagSchemas)().map(name => {
|
|
45
|
+
const flags = (0, examples_1.getDemoFlagSchema)(name);
|
|
46
|
+
return (react_1.default.createElement("option", { key: name, value: name },
|
|
47
|
+
name.charAt(0).toUpperCase() + name.slice(1),
|
|
48
|
+
" (",
|
|
49
|
+
flags?.flags.length || 0,
|
|
50
|
+
" flags)"));
|
|
51
|
+
}))));
|
|
52
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ExampleLoaderButton - Compact button for loading examples
|
|
3
|
+
*
|
|
4
|
+
* Debug tool for loading example dialogues and flag schemas.
|
|
5
|
+
* Only shown when ENABLE_DEBUG_TOOLS is true.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import { DialogueTree } from '../types';
|
|
9
|
+
import { FlagSchema } from '../types/flags';
|
|
10
|
+
interface ExampleLoaderButtonProps {
|
|
11
|
+
onLoadDialogue: (dialogue: DialogueTree) => void;
|
|
12
|
+
onLoadFlags: (flags: FlagSchema) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare function ExampleLoaderButton({ onLoadDialogue, onLoadFlags }: ExampleLoaderButtonProps): React.JSX.Element;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ExampleLoaderButton - Compact button for loading examples
|
|
4
|
+
*
|
|
5
|
+
* Debug tool for loading example dialogues and flag schemas.
|
|
6
|
+
* Only shown when ENABLE_DEBUG_TOOLS is true.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.ExampleLoaderButton = ExampleLoaderButton;
|
|
43
|
+
const react_1 = __importStar(require("react"));
|
|
44
|
+
const examples_1 = require("../examples");
|
|
45
|
+
const lucide_react_1 = require("lucide-react");
|
|
46
|
+
function ExampleLoaderButton({ onLoadDialogue, onLoadFlags }) {
|
|
47
|
+
const [showMenu, setShowMenu] = (0, react_1.useState)(false);
|
|
48
|
+
const handleDialogueChange = (name) => {
|
|
49
|
+
const dialogue = (0, examples_1.getExampleDialogue)(name);
|
|
50
|
+
if (dialogue) {
|
|
51
|
+
onLoadDialogue(dialogue);
|
|
52
|
+
setShowMenu(false);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
const handleFlagsChange = (name) => {
|
|
56
|
+
const flags = (0, examples_1.getDemoFlagSchema)(name);
|
|
57
|
+
if (flags) {
|
|
58
|
+
onLoadFlags(flags);
|
|
59
|
+
setShowMenu(false);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
return (react_1.default.createElement("div", { className: "relative" },
|
|
63
|
+
react_1.default.createElement("button", { onClick: () => setShowMenu(!showMenu), className: `p-1.5 rounded transition-colors ${showMenu
|
|
64
|
+
? 'bg-[#e94560]/20 text-[#e94560] border border-[#e94560]/50'
|
|
65
|
+
: 'bg-[#12121a] border border-[#2a2a3e] text-gray-400 hover:text-white hover:border-[#3a3a4e]'}`, title: "Load Examples (Debug Tool)" },
|
|
66
|
+
react_1.default.createElement(lucide_react_1.FileCode, { size: 14 })),
|
|
67
|
+
showMenu && (react_1.default.createElement("div", { className: "absolute left-full ml-2 top-0 z-50 bg-[#0d0d14] border border-[#2a2a3e] rounded-lg shadow-xl p-1 min-w-[250px]" },
|
|
68
|
+
react_1.default.createElement("div", { className: "text-[10px] text-gray-500 uppercase tracking-wider px-2 py-1 border-b border-[#2a2a3e]" }, "Load Examples"),
|
|
69
|
+
react_1.default.createElement("div", { className: "px-2 py-1" },
|
|
70
|
+
react_1.default.createElement("div", { className: "text-xs text-gray-400 mb-1" }, "Dialogue Examples"),
|
|
71
|
+
react_1.default.createElement("select", { onChange: (e) => {
|
|
72
|
+
if (e.target.value)
|
|
73
|
+
handleDialogueChange(e.target.value);
|
|
74
|
+
}, defaultValue: "", className: "w-full bg-[#12121a] border border-[#2a2a3e] text-white text-xs px-2 py-1.5 rounded hover:border-[#3a3a4e] focus:outline-none focus:border-[#e94560] cursor-pointer" },
|
|
75
|
+
react_1.default.createElement("option", { value: "" }, "Select dialogue..."),
|
|
76
|
+
(0, examples_1.listExamples)().map(name => {
|
|
77
|
+
const dialogue = (0, examples_1.getExampleDialogue)(name);
|
|
78
|
+
if (!dialogue)
|
|
79
|
+
return null;
|
|
80
|
+
const nodeCount = Object.keys(dialogue.nodes).length;
|
|
81
|
+
return (react_1.default.createElement("option", { key: name, value: name },
|
|
82
|
+
dialogue.title,
|
|
83
|
+
" (",
|
|
84
|
+
nodeCount,
|
|
85
|
+
" nodes)"));
|
|
86
|
+
}).filter(Boolean))),
|
|
87
|
+
react_1.default.createElement("div", { className: "px-2 py-1 border-t border-[#2a2a3e]" },
|
|
88
|
+
react_1.default.createElement("div", { className: "text-xs text-gray-400 mb-1" }, "Flag Schemas"),
|
|
89
|
+
react_1.default.createElement("select", { onChange: (e) => {
|
|
90
|
+
if (e.target.value)
|
|
91
|
+
handleFlagsChange(e.target.value);
|
|
92
|
+
}, defaultValue: "", className: "w-full bg-[#12121a] border border-[#2a2a3e] text-white text-xs px-2 py-1.5 rounded hover:border-[#3a3a4e] focus:outline-none focus:border-[#e94560] cursor-pointer" },
|
|
93
|
+
react_1.default.createElement("option", { value: "" }, "Select schema..."),
|
|
94
|
+
(0, examples_1.listDemoFlagSchemas)().map(name => {
|
|
95
|
+
const flags = (0, examples_1.getDemoFlagSchema)(name);
|
|
96
|
+
return (react_1.default.createElement("option", { key: name, value: name },
|
|
97
|
+
name.charAt(0).toUpperCase() + name.slice(1),
|
|
98
|
+
" (",
|
|
99
|
+
flags?.flags.length || 0,
|
|
100
|
+
" flags)"));
|
|
101
|
+
})))))));
|
|
102
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FlagSchema } from '../types/flags';
|
|
3
|
+
import { DialogueTree } from '../types';
|
|
4
|
+
interface FlagManagerProps {
|
|
5
|
+
flagSchema: FlagSchema;
|
|
6
|
+
dialogue?: DialogueTree;
|
|
7
|
+
onUpdate: (schema: FlagSchema) => void;
|
|
8
|
+
onClose: () => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function FlagManager({ flagSchema, dialogue, onUpdate, onClose }: FlagManagerProps): React.JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.FlagManager = FlagManager;
|
|
37
|
+
const react_1 = __importStar(require("react"));
|
|
38
|
+
const flagTypeColors = {
|
|
39
|
+
dialogue: 'bg-gray-500/20 text-gray-400 border-gray-500/30',
|
|
40
|
+
quest: 'bg-blue-500/20 text-blue-400 border-blue-500/30',
|
|
41
|
+
achievement: 'bg-yellow-500/20 text-yellow-400 border-yellow-500/30',
|
|
42
|
+
item: 'bg-green-500/20 text-green-400 border-green-500/30',
|
|
43
|
+
stat: 'bg-purple-500/20 text-purple-400 border-purple-500/30',
|
|
44
|
+
title: 'bg-pink-500/20 text-pink-400 border-pink-500/30',
|
|
45
|
+
global: 'bg-orange-500/20 text-orange-400 border-orange-500/30',
|
|
46
|
+
};
|
|
47
|
+
const flagTypeLabels = {
|
|
48
|
+
dialogue: 'Dialogue',
|
|
49
|
+
quest: 'Quest',
|
|
50
|
+
achievement: 'Achievement',
|
|
51
|
+
item: 'Item',
|
|
52
|
+
stat: 'Stat',
|
|
53
|
+
title: 'Title',
|
|
54
|
+
global: 'Global',
|
|
55
|
+
};
|
|
56
|
+
const flagTypeIcons = {
|
|
57
|
+
dialogue: '💬',
|
|
58
|
+
quest: '📜',
|
|
59
|
+
achievement: '🏆',
|
|
60
|
+
item: '🎒',
|
|
61
|
+
stat: '📊',
|
|
62
|
+
title: '👑',
|
|
63
|
+
global: '🌐',
|
|
64
|
+
};
|
|
65
|
+
function FlagManager({ flagSchema, dialogue, onUpdate, onClose }) {
|
|
66
|
+
const [editingFlag, setEditingFlag] = (0, react_1.useState)(null);
|
|
67
|
+
const [isCreating, setIsCreating] = (0, react_1.useState)(false);
|
|
68
|
+
const [selectedSection, setSelectedSection] = (0, react_1.useState)('all');
|
|
69
|
+
// Find all flags used in the dialogue tree
|
|
70
|
+
const usedFlags = (0, react_1.useMemo)(() => {
|
|
71
|
+
if (!dialogue)
|
|
72
|
+
return new Set();
|
|
73
|
+
const used = new Set();
|
|
74
|
+
Object.values(dialogue.nodes).forEach(node => {
|
|
75
|
+
if (node.setFlags) {
|
|
76
|
+
node.setFlags.forEach(flagId => used.add(flagId));
|
|
77
|
+
}
|
|
78
|
+
if (node.choices) {
|
|
79
|
+
node.choices.forEach(choice => {
|
|
80
|
+
if (choice.setFlags) {
|
|
81
|
+
choice.setFlags.forEach(flagId => used.add(flagId));
|
|
82
|
+
}
|
|
83
|
+
if (choice.conditions) {
|
|
84
|
+
choice.conditions.forEach(cond => used.add(cond.flag));
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
return used;
|
|
90
|
+
}, [dialogue]);
|
|
91
|
+
// Group flags by type
|
|
92
|
+
const flagsByType = (0, react_1.useMemo)(() => {
|
|
93
|
+
const grouped = {
|
|
94
|
+
all: flagSchema.flags,
|
|
95
|
+
};
|
|
96
|
+
Object.keys(flagTypeLabels).forEach(type => {
|
|
97
|
+
grouped[type] = flagSchema.flags.filter(f => f.type === type);
|
|
98
|
+
});
|
|
99
|
+
return grouped;
|
|
100
|
+
}, [flagSchema.flags]);
|
|
101
|
+
const currentFlags = flagsByType[selectedSection] || [];
|
|
102
|
+
const handleCreateFlag = (type) => {
|
|
103
|
+
const newFlag = {
|
|
104
|
+
id: 'new_flag',
|
|
105
|
+
name: 'New Flag',
|
|
106
|
+
type: type || 'dialogue',
|
|
107
|
+
};
|
|
108
|
+
setEditingFlag(newFlag);
|
|
109
|
+
setIsCreating(true);
|
|
110
|
+
};
|
|
111
|
+
const handleSaveFlag = (flag) => {
|
|
112
|
+
if (isCreating) {
|
|
113
|
+
onUpdate({
|
|
114
|
+
...flagSchema,
|
|
115
|
+
flags: [...flagSchema.flags, flag]
|
|
116
|
+
});
|
|
117
|
+
setIsCreating(false);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
onUpdate({
|
|
121
|
+
...flagSchema,
|
|
122
|
+
flags: flagSchema.flags.map(f => f.id === flag.id ? flag : f)
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
setEditingFlag(null);
|
|
126
|
+
};
|
|
127
|
+
const handleDeleteFlag = (flagId) => {
|
|
128
|
+
if (confirm(`Delete flag "${flagId}"?`)) {
|
|
129
|
+
onUpdate({
|
|
130
|
+
...flagSchema,
|
|
131
|
+
flags: flagSchema.flags.filter(f => f.id !== flagId)
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
// Get counts for each section
|
|
136
|
+
const sectionCounts = (0, react_1.useMemo)(() => {
|
|
137
|
+
const counts = { all: flagSchema.flags.length };
|
|
138
|
+
Object.keys(flagTypeLabels).forEach(type => {
|
|
139
|
+
counts[type] = flagsByType[type].length;
|
|
140
|
+
});
|
|
141
|
+
return counts;
|
|
142
|
+
}, [flagSchema.flags, flagsByType]);
|
|
143
|
+
return (react_1.default.createElement("div", { className: "fixed inset-0 bg-black/70 z-50 flex items-center justify-center p-4", onClick: (e) => {
|
|
144
|
+
if (e.target === e.currentTarget) {
|
|
145
|
+
onClose();
|
|
146
|
+
}
|
|
147
|
+
} },
|
|
148
|
+
react_1.default.createElement("div", { className: "bg-[#0d0d14] border border-[#1a1a2e] rounded-xl max-w-6xl w-full max-h-[90vh] overflow-hidden flex flex-col", onClick: (e) => e.stopPropagation() },
|
|
149
|
+
react_1.default.createElement("div", { className: "p-4 border-b border-[#1a1a2e] flex items-center justify-between flex-shrink-0" },
|
|
150
|
+
react_1.default.createElement("div", null,
|
|
151
|
+
react_1.default.createElement("h2", { className: "text-lg font-semibold text-white" }, "Flag Manager"),
|
|
152
|
+
react_1.default.createElement("p", { className: "text-xs text-gray-500 mt-1" }, dialogue && (react_1.default.createElement("span", null,
|
|
153
|
+
react_1.default.createElement("span", { className: "text-[#e94560] font-semibold" }, usedFlags.size),
|
|
154
|
+
react_1.default.createElement("span", { className: "text-gray-500" }, " / "),
|
|
155
|
+
react_1.default.createElement("span", { className: "text-gray-400" }, flagSchema.flags.length),
|
|
156
|
+
react_1.default.createElement("span", { className: "text-gray-500" }, " flags used in dialogue"))))),
|
|
157
|
+
react_1.default.createElement("div", { className: "flex gap-2" },
|
|
158
|
+
react_1.default.createElement("button", { onClick: () => handleCreateFlag(selectedSection !== 'all' ? selectedSection : undefined), className: "px-3 py-1.5 bg-[#e94560] hover:bg-[#d63850] text-white text-sm rounded flex items-center gap-2" },
|
|
159
|
+
react_1.default.createElement("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2" },
|
|
160
|
+
react_1.default.createElement("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
|
|
161
|
+
react_1.default.createElement("line", { x1: "5", y1: "12", x2: "19", y2: "12" })),
|
|
162
|
+
"New Flag"),
|
|
163
|
+
react_1.default.createElement("button", { onClick: (e) => {
|
|
164
|
+
e.stopPropagation();
|
|
165
|
+
onClose();
|
|
166
|
+
}, className: "p-1.5 text-gray-400 hover:text-white transition-colors", title: "Close" },
|
|
167
|
+
react_1.default.createElement("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2" },
|
|
168
|
+
react_1.default.createElement("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
169
|
+
react_1.default.createElement("line", { x1: "6", y1: "6", x2: "18", y2: "18" }))))),
|
|
170
|
+
react_1.default.createElement("div", { className: "flex-1 flex overflow-hidden" },
|
|
171
|
+
react_1.default.createElement("div", { className: "w-64 border-r border-[#1a1a2e] bg-[#12121a] flex flex-col flex-shrink-0" },
|
|
172
|
+
react_1.default.createElement("div", { className: "p-4 border-b border-[#1a1a2e]" },
|
|
173
|
+
react_1.default.createElement("div", { className: "text-xs text-gray-500 uppercase tracking-wider mb-3" }, "Sections"),
|
|
174
|
+
react_1.default.createElement("nav", { className: "space-y-1" },
|
|
175
|
+
react_1.default.createElement("button", { onClick: () => setSelectedSection('all'), className: `w-full text-left px-3 py-2 rounded text-sm transition-colors flex items-center justify-between ${selectedSection === 'all'
|
|
176
|
+
? 'bg-[#e94560]/20 text-[#e94560] border border-[#e94560]/30'
|
|
177
|
+
: 'text-gray-400 hover:bg-[#1a1a2e] hover:text-white'}` },
|
|
178
|
+
react_1.default.createElement("span", null, "All Flags"),
|
|
179
|
+
react_1.default.createElement("span", { className: "text-xs text-gray-500" }, sectionCounts.all)),
|
|
180
|
+
Object.entries(flagTypeLabels).map(([type, label]) => (react_1.default.createElement("button", { key: type, onClick: () => setSelectedSection(type), className: `w-full text-left px-3 py-2 rounded text-sm transition-colors flex items-center justify-between ${selectedSection === type
|
|
181
|
+
? `${flagTypeColors[type]} border`
|
|
182
|
+
: 'text-gray-400 hover:bg-[#1a1a2e] hover:text-white'}` },
|
|
183
|
+
react_1.default.createElement("span", { className: "flex items-center gap-2" },
|
|
184
|
+
react_1.default.createElement("span", null, flagTypeIcons[type]),
|
|
185
|
+
react_1.default.createElement("span", null, label)),
|
|
186
|
+
react_1.default.createElement("span", { className: "text-xs text-gray-500" }, sectionCounts[type] || 0)))))),
|
|
187
|
+
react_1.default.createElement("div", { className: "p-4 border-t border-[#1a1a2e] mt-auto" },
|
|
188
|
+
react_1.default.createElement("div", { className: "text-xs text-gray-500 uppercase tracking-wider mb-2" }, "Info"),
|
|
189
|
+
react_1.default.createElement("div", { className: "text-xs text-gray-400 space-y-1" },
|
|
190
|
+
react_1.default.createElement("p", null,
|
|
191
|
+
react_1.default.createElement("span", { className: "text-gray-500" }, "Dialogue flags"),
|
|
192
|
+
" (gray) are temporary and reset after dialogue ends."),
|
|
193
|
+
react_1.default.createElement("p", null,
|
|
194
|
+
react_1.default.createElement("span", { className: "text-white" }, "Game flags"),
|
|
195
|
+
" (colored) persist and affect the entire game.")))),
|
|
196
|
+
react_1.default.createElement("div", { className: "flex-1 overflow-y-auto" }, editingFlag ? (react_1.default.createElement("div", { className: "p-6" },
|
|
197
|
+
react_1.default.createElement(FlagEditor, { flag: editingFlag, categories: flagSchema.categories || [], onSave: handleSaveFlag, onCancel: () => { setEditingFlag(null); setIsCreating(false); } }))) : (react_1.default.createElement("div", { className: "p-6" }, currentFlags.length === 0 ? (react_1.default.createElement("div", { className: "text-center py-12 text-gray-500" },
|
|
198
|
+
react_1.default.createElement("p", { className: "mb-4" },
|
|
199
|
+
"No ",
|
|
200
|
+
selectedSection === 'all' ? '' : flagTypeLabels[selectedSection],
|
|
201
|
+
" flags defined yet."),
|
|
202
|
+
react_1.default.createElement("button", { onClick: () => handleCreateFlag(selectedSection !== 'all' ? selectedSection : undefined), className: "px-4 py-2 bg-[#e94560] hover:bg-[#d63850] text-white rounded" },
|
|
203
|
+
"Create ",
|
|
204
|
+
selectedSection === 'all' ? 'a' : flagTypeLabels[selectedSection],
|
|
205
|
+
" Flag"))) : (react_1.default.createElement("div", { className: "space-y-2" }, currentFlags.map(flag => {
|
|
206
|
+
const isUsed = usedFlags.has(flag.id);
|
|
207
|
+
return (react_1.default.createElement("div", { key: flag.id, className: `bg-[#12121a] border rounded-lg p-4 hover:bg-[#1a1a2e] transition-colors ${isUsed ? 'border-l-4 border-l-[#e94560]' : 'border-[#1a1a2e]'}` },
|
|
208
|
+
react_1.default.createElement("div", { className: "flex items-start justify-between gap-4" },
|
|
209
|
+
react_1.default.createElement("div", { className: "flex-1 min-w-0" },
|
|
210
|
+
react_1.default.createElement("div", { className: "flex items-center gap-2 mb-2" },
|
|
211
|
+
react_1.default.createElement("span", { className: `px-2 py-1 rounded text-xs font-medium border ${flagTypeColors[flag.type]}` }, flagTypeLabels[flag.type]),
|
|
212
|
+
react_1.default.createElement("span", { className: "font-mono text-sm text-white" }, flag.id),
|
|
213
|
+
isUsed && (react_1.default.createElement("span", { className: "text-[10px] px-1.5 py-0.5 bg-[#e94560]/20 text-[#e94560] rounded border border-[#e94560]/30" }, "Used"))),
|
|
214
|
+
flag.name !== flag.id && (react_1.default.createElement("div", { className: "text-sm text-gray-300 mb-1" }, flag.name)),
|
|
215
|
+
flag.description && (react_1.default.createElement("div", { className: "text-xs text-gray-500 mt-1" }, flag.description)),
|
|
216
|
+
react_1.default.createElement("div", { className: "flex items-center gap-3 mt-2" },
|
|
217
|
+
flag.category && (react_1.default.createElement("span", { className: "text-xs text-gray-500" },
|
|
218
|
+
"Category: ",
|
|
219
|
+
flag.category)),
|
|
220
|
+
flag.valueType && (react_1.default.createElement("span", { className: "text-xs text-gray-500" },
|
|
221
|
+
"Type: ",
|
|
222
|
+
flag.valueType)),
|
|
223
|
+
flag.defaultValue !== undefined && (react_1.default.createElement("span", { className: "text-xs text-gray-500" },
|
|
224
|
+
"Default: ",
|
|
225
|
+
String(flag.defaultValue))))),
|
|
226
|
+
react_1.default.createElement("div", { className: "flex gap-1 flex-shrink-0" },
|
|
227
|
+
react_1.default.createElement("button", { onClick: () => setEditingFlag(flag), className: "p-2 text-gray-400 hover:text-white hover:bg-[#2a2a3e] rounded transition-colors", title: "Edit" },
|
|
228
|
+
react_1.default.createElement("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2" },
|
|
229
|
+
react_1.default.createElement("path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }),
|
|
230
|
+
react_1.default.createElement("path", { d: "M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" }))),
|
|
231
|
+
react_1.default.createElement("button", { onClick: () => handleDeleteFlag(flag.id), className: "p-2 text-gray-400 hover:text-red-400 hover:bg-red-500/10 rounded transition-colors", title: "Delete" },
|
|
232
|
+
react_1.default.createElement("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2" },
|
|
233
|
+
react_1.default.createElement("polyline", { points: "3 6 5 6 21 6" }),
|
|
234
|
+
react_1.default.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })))))));
|
|
235
|
+
}))))))))));
|
|
236
|
+
}
|
|
237
|
+
function FlagEditor({ flag, categories, onSave, onCancel }) {
|
|
238
|
+
const [edited, setEdited] = (0, react_1.useState)(flag);
|
|
239
|
+
const flagTypes = ['dialogue', 'quest', 'achievement', 'item', 'stat', 'title', 'global'];
|
|
240
|
+
return (react_1.default.createElement("div", { className: "space-y-4 max-w-2xl" },
|
|
241
|
+
react_1.default.createElement("div", null,
|
|
242
|
+
react_1.default.createElement("label", { className: "text-xs text-gray-500 uppercase block mb-1" }, "Flag ID"),
|
|
243
|
+
react_1.default.createElement("input", { type: "text", value: edited.id, onChange: (e) => setEdited({ ...edited, id: e.target.value }), className: "w-full bg-[#12121a] border border-[#2a2a3e] rounded px-2 py-1.5 text-sm text-gray-200 font-mono focus:border-[#e94560] outline-none", placeholder: "quest_dragon_slayer" }),
|
|
244
|
+
react_1.default.createElement("p", { className: "text-xs text-gray-500 mt-1" }, "Use prefixes: quest_, item_, stat_, etc.")),
|
|
245
|
+
react_1.default.createElement("div", null,
|
|
246
|
+
react_1.default.createElement("label", { className: "text-xs text-gray-500 uppercase block mb-1" }, "Display Name"),
|
|
247
|
+
react_1.default.createElement("input", { type: "text", value: edited.name, onChange: (e) => setEdited({ ...edited, name: e.target.value }), className: "w-full bg-[#12121a] border border-[#2a2a3e] rounded px-2 py-1.5 text-sm text-gray-200 focus:border-[#e94560] outline-none", placeholder: "Dragon Slayer Quest" })),
|
|
248
|
+
react_1.default.createElement("div", null,
|
|
249
|
+
react_1.default.createElement("label", { className: "text-xs text-gray-500 uppercase block mb-1" }, "Description"),
|
|
250
|
+
react_1.default.createElement("textarea", { value: edited.description || '', onChange: (e) => setEdited({ ...edited, description: e.target.value }), className: "w-full bg-[#12121a] border border-[#2a2a3e] rounded px-2 py-1.5 text-sm text-gray-200 focus:border-[#e94560] outline-none min-h-[60px] resize-y", placeholder: "Optional description..." })),
|
|
251
|
+
react_1.default.createElement("div", null,
|
|
252
|
+
react_1.default.createElement("label", { className: "text-xs text-gray-500 uppercase block mb-1" }, "Flag Type"),
|
|
253
|
+
react_1.default.createElement("div", { className: "grid grid-cols-2 gap-2" }, flagTypes.map(type => (react_1.default.createElement("button", { key: type, onClick: () => setEdited({ ...edited, type }), className: `px-3 py-2 rounded text-sm border transition-colors ${edited.type === type
|
|
254
|
+
? flagTypeColors[type] + ' border-current'
|
|
255
|
+
: 'bg-[#12121a] border-[#2a2a3e] text-gray-400 hover:border-[#3a3a4e]'}` }, flagTypeLabels[type])))),
|
|
256
|
+
react_1.default.createElement("p", { className: "text-xs text-gray-500 mt-2" }, edited.type === 'dialogue' ? (react_1.default.createElement("span", { className: "text-gray-400" }, "Temporary flag - resets after dialogue ends")) : (react_1.default.createElement("span", { className: "text-white" }, "Persistent flag - affects entire game")))),
|
|
257
|
+
react_1.default.createElement("div", null,
|
|
258
|
+
react_1.default.createElement("label", { className: "text-xs text-gray-500 uppercase block mb-1" }, "Category"),
|
|
259
|
+
react_1.default.createElement("input", { type: "text", value: edited.category || '', onChange: (e) => setEdited({ ...edited, category: e.target.value }), className: "w-full bg-[#12121a] border border-[#2a2a3e] rounded px-2 py-1.5 text-sm text-gray-200 focus:border-[#e94560] outline-none", placeholder: "quests, items, stats, etc.", list: "categories" }),
|
|
260
|
+
react_1.default.createElement("datalist", { id: "categories" }, categories.map(cat => react_1.default.createElement("option", { key: cat, value: cat })))),
|
|
261
|
+
react_1.default.createElement("div", null,
|
|
262
|
+
react_1.default.createElement("label", { className: "text-xs text-gray-500 uppercase block mb-1" }, "Value Type"),
|
|
263
|
+
react_1.default.createElement("select", { value: edited.valueType || '', onChange: (e) => setEdited({ ...edited, valueType: e.target.value }), className: "w-full bg-[#12121a] border border-[#2a2a3e] rounded px-2 py-1.5 text-sm text-gray-200 focus:border-[#e94560] outline-none" },
|
|
264
|
+
react_1.default.createElement("option", { value: "" }, "Boolean (true/false)"),
|
|
265
|
+
react_1.default.createElement("option", { value: "number" }, "Number"),
|
|
266
|
+
react_1.default.createElement("option", { value: "string" }, "String"))),
|
|
267
|
+
edited.valueType && (react_1.default.createElement("div", null,
|
|
268
|
+
react_1.default.createElement("label", { className: "text-xs text-gray-500 uppercase block mb-1" }, "Default Value"),
|
|
269
|
+
react_1.default.createElement("input", { type: edited.valueType === 'number' ? 'number' : 'text', value: edited.defaultValue?.toString() || '', onChange: (e) => {
|
|
270
|
+
let value = e.target.value;
|
|
271
|
+
if (edited.valueType === 'number') {
|
|
272
|
+
value = parseFloat(value) || 0;
|
|
273
|
+
}
|
|
274
|
+
else if (edited.valueType === 'boolean') {
|
|
275
|
+
value = value === 'true';
|
|
276
|
+
}
|
|
277
|
+
setEdited({ ...edited, defaultValue: value });
|
|
278
|
+
}, className: "w-full bg-[#12121a] border border-[#2a2a3e] rounded px-2 py-1.5 text-sm text-gray-200 focus:border-[#e94560] outline-none", placeholder: edited.valueType === 'number' ? '0' : edited.valueType === 'string' ? '""' : 'false' }))),
|
|
279
|
+
react_1.default.createElement("div", { className: "flex gap-2 pt-4 border-t border-[#1a1a2e]" },
|
|
280
|
+
react_1.default.createElement("button", { onClick: () => onSave(edited), className: "flex-1 px-4 py-2 bg-[#e94560] hover:bg-[#d63850] text-white rounded" }, "Save Flag"),
|
|
281
|
+
react_1.default.createElement("button", { onClick: onCancel, className: "px-4 py-2 bg-[#12121a] hover:bg-[#1a1a2e] text-gray-300 rounded" }, "Cancel"))));
|
|
282
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FlagSchema } from '../types/flags';
|
|
3
|
+
import 'react-tooltip/dist/react-tooltip.css';
|
|
4
|
+
interface FlagSelectorProps {
|
|
5
|
+
value: string[];
|
|
6
|
+
onChange: (flags: string[]) => void;
|
|
7
|
+
flagSchema?: FlagSchema;
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function FlagSelector({ value, onChange, flagSchema, placeholder }: FlagSelectorProps): React.JSX.Element;
|
|
11
|
+
export {};
|