jaml-ui 0.24.16 → 0.24.19
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/components/DeckSprite.js +2 -0
- package/dist/components/GameCard.js +1 -0
- package/dist/components/JamlAestheticSelector.js +3 -2
- package/dist/components/JamlCurator.js +3 -2
- package/dist/components/JamlIde.d.ts +4 -3
- package/dist/components/JamlIde.js +3 -31
- package/dist/components/JamlIdeToolbar.d.ts +1 -1
- package/dist/components/JamlIdeToolbar.js +5 -5
- package/dist/components/JamlMapPreview.js +3 -37
- package/dist/components/Jimbolate.d.ts +7 -0
- package/dist/components/Jimbolate.js +17 -0
- package/dist/components/PaginatedFilterBrowser.d.ts +23 -0
- package/dist/components/PaginatedFilterBrowser.js +54 -0
- package/dist/components/RunConfigModal.js +11 -150
- package/dist/components/jamlMap/CategoryPicker.d.ts +1 -2
- package/dist/components/jamlMap/CategoryPicker.js +2 -1
- package/dist/components/jamlMap/JamlMapEditor.js +8 -10
- package/dist/components/jamlMap/JokerPicker.d.ts +1 -2
- package/dist/components/jamlMap/JokerPicker.js +3 -7
- package/dist/components/jamlMap/MysterySlot.js +0 -15
- package/dist/hooks/searchWorker.d.ts +1 -29
- package/dist/hooks/searchWorker.js +8 -6
- package/dist/hooks/useIntersectionObserver.js +5 -3
- package/dist/hooks/useSearch.js +5 -1
- package/dist/hooks/useShopStream.js +5 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/lib/cardParser.d.ts +1 -1
- package/dist/lib/cardParser.js +19 -17
- package/dist/lib/classes/BuyMetaData.d.ts +2 -2
- package/dist/lib/const.d.ts +22 -13
- package/dist/lib/data/constants.js +10 -9
- package/dist/lib/hooks/useJamlFilter.js +5 -5
- package/dist/lib/hooks/useSeedAnalyzer.js +7 -1
- package/dist/lib/jaml/jamlSchema.d.ts +18 -3
- package/dist/lib/jaml/jamlSchema.js +2 -2
- package/dist/lib/parseDailyRitual.d.ts +1 -1
- package/dist/lib/parseDailyRitual.js +2 -1
- package/dist/r3f/Card3D.js +2 -0
- package/dist/r3f/JimboBillboard.d.ts +1 -1
- package/dist/r3f/JimboBillboard.js +5 -2
- package/dist/ui/JimboInputModal.js +8 -2
- package/dist/ui/PanelSplitter.js +4 -2
- package/dist/ui/hooks.js +14 -5
- package/dist/ui/ide/JamlEditor.js +53 -63
- package/dist/ui/jimbo.css +70 -16
- package/dist/ui/jimboTooltip.js +12 -6
- package/dist/ui/panel.d.ts +1 -2
- package/dist/ui/panel.js +2 -2
- package/dist/ui/radial/RadialButton.js +1 -1
- package/dist/ui/showcase.js +1 -1
- package/dist/utils/jamlMapPreview.js +2 -1
- package/dist/utils/jamlVisualFilter.js +3 -2
- package/package.json +21 -16
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { resolveJamlAssetUrl } from '../assets.js';
|
|
4
|
+
// eslint-disable-next-line react-refresh/only-export-components
|
|
4
5
|
export const DECK_SPRITE_POS = {
|
|
5
6
|
red: { x: 0, y: 0 },
|
|
6
7
|
nebula: { x: 3, y: 0 },
|
|
@@ -20,6 +21,7 @@ export const DECK_SPRITE_POS = {
|
|
|
20
21
|
anaglyph: { x: 2, y: 4 },
|
|
21
22
|
zodiac: { x: 3, y: 4 },
|
|
22
23
|
};
|
|
24
|
+
// eslint-disable-next-line react-refresh/only-export-components
|
|
23
25
|
export const STAKE_SPRITE_POS = {
|
|
24
26
|
white: { x: 1, y: 0 },
|
|
25
27
|
red: { x: 2, y: 0 },
|
|
@@ -153,6 +153,7 @@ function resolvePackedAnalyzerItem(item, scale) {
|
|
|
153
153
|
}
|
|
154
154
|
return { kind: "unknown", label: displayName };
|
|
155
155
|
}
|
|
156
|
+
// eslint-disable-next-line react-refresh/only-export-components
|
|
156
157
|
export function resolveAnalyzerShopItem(item, scale = 1) {
|
|
157
158
|
const displayName = String(item.name || "").trim();
|
|
158
159
|
if (!displayName) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { JimboText } from "../ui/jimboText.js";
|
|
4
|
+
import { JimboButton } from "../ui/panel.js";
|
|
4
5
|
const AESTHETICS = [
|
|
5
6
|
{ id: "Palindrome", value: 0, label: "Palindrome", desc: "Seeds that read the same forwards and backwards" },
|
|
6
7
|
{ id: "Psychosis", value: 1, label: "Psychosis", desc: "Unsettling or eerie seed patterns" },
|
|
@@ -14,8 +15,8 @@ const AESTHETICS = [
|
|
|
14
15
|
* All styling via jimbo.css `.j-aesthetic-selector` / `.j-aesthetic-pill` — zero inline styles.
|
|
15
16
|
*/
|
|
16
17
|
export function JamlAestheticSelector({ value, onChange, className, style }) {
|
|
17
|
-
return (_jsxs("div", { className: `j-aesthetic-selector ${className ?? ""}`, style: style, children: [_jsx(JimboText, { size: "xs", tone: "grey", children: "Seed Aesthetics" }), _jsx("div", {
|
|
18
|
+
return (_jsxs("div", { className: `j-aesthetic-selector ${className ?? ""}`, style: style, children: [_jsx(JimboText, { size: "xs", tone: "grey", children: "Seed Aesthetics" }), _jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, marginTop: 4 }, children: AESTHETICS.map((a) => {
|
|
18
19
|
const isActive = value === a.id;
|
|
19
|
-
return (_jsx(
|
|
20
|
+
return (_jsx(JimboButton, { tone: isActive ? "red" : "grey", size: "sm", onClick: () => onChange(isActive ? null : a.id, a.value), children: a.label }, a.id));
|
|
20
21
|
}) })] }));
|
|
21
22
|
}
|
|
@@ -40,8 +40,9 @@ export function JamlCurator({ motely, motelyWasmUrl }) {
|
|
|
40
40
|
};
|
|
41
41
|
return (_jsx("div", { style: {
|
|
42
42
|
width: "100%",
|
|
43
|
-
maxWidth:
|
|
44
|
-
height: "
|
|
43
|
+
maxWidth: 375,
|
|
44
|
+
height: "100dvh",
|
|
45
|
+
maxHeight: 812,
|
|
45
46
|
margin: "0 auto",
|
|
46
47
|
position: "relative",
|
|
47
48
|
background: C.DARKEST,
|
|
@@ -25,8 +25,9 @@ export interface JamlIdeProps {
|
|
|
25
25
|
codePlaceholder?: string;
|
|
26
26
|
onSearch?: () => void;
|
|
27
27
|
isSearching?: boolean;
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
onTestSeed?: (seed: string) => void;
|
|
29
|
+
jimbolateResult?: "idle" | "match" | "nomatch" | "running" | "error";
|
|
30
|
+
jimbolateError?: string | null;
|
|
30
31
|
/**
|
|
31
32
|
* Controlled visual filter. When provided alongside `onVisualFilterChange`, the Visual tab
|
|
32
33
|
* is fully controlled by the parent. When absent, the Visual tab auto-derives from the text.
|
|
@@ -36,4 +37,4 @@ export interface JamlIdeProps {
|
|
|
36
37
|
}
|
|
37
38
|
export type { JamlVisualFilter } from "./JamlIdeVisual.js";
|
|
38
39
|
export type { JamlVisualClause, JamlZone } from "./JamlIdeVisual.js";
|
|
39
|
-
export declare function JamlIde({ jaml, defaultJaml, onChange, defaultMode, searchResults, className, style, title, subtitle, compactHeader, actions, codePlaceholder, onSearch, isSearching,
|
|
40
|
+
export declare function JamlIde({ jaml, defaultJaml, onChange, defaultMode, searchResults, className, style, title, subtitle, compactHeader, actions, codePlaceholder, onSearch, isSearching, onTestSeed, jimbolateResult, jimbolateError, visualFilter, onVisualFilterChange, }: JamlIdeProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useMemo, useState } from "react";
|
|
4
|
-
import { JimboBalatroFooter } from "../ui/footer.js";
|
|
5
4
|
import { JamlMapPreview } from "./JamlMapPreview.js";
|
|
6
5
|
import { JamlMapEditor, CategoryMenu, JokerPicker, CategoryPicker, VOUCHER_PICKER_CONFIG, TAG_PICKER_CONFIG, BOSS_PICKER_CONFIG, TAROT_PICKER_CONFIG, PLANET_PICKER_CONFIG, SPECTRAL_PICKER_CONFIG, PACK_PICKER_CONFIG, } from "./jamlMap/index.js";
|
|
7
6
|
import { JamlIdeToolbar } from "./JamlIdeToolbar.js";
|
|
8
7
|
import { JamlIdeVisual } from "./JamlIdeVisual.js";
|
|
9
8
|
import { JamlCodeEditor } from "./JamlCodeEditor.js";
|
|
9
|
+
import { Jimbolate } from "./Jimbolate.js";
|
|
10
10
|
import { JimboColorOption } from "../ui/tokens.js";
|
|
11
11
|
import { JimboModal } from "../ui/panel.js";
|
|
12
12
|
import { jamlTextToVisualFilter, visualFilterToJamlText } from "../utils/jamlVisualFilter.js";
|
|
13
|
-
import { DeckSprite } from "./DeckSprite.js";
|
|
14
13
|
const CATEGORY_CONFIG_MAP = {
|
|
15
14
|
voucher: VOUCHER_PICKER_CONFIG,
|
|
16
15
|
tag: TAG_PICKER_CONFIG,
|
|
@@ -90,34 +89,7 @@ function ResultsView({ results, jaml }) {
|
|
|
90
89
|
})] })] })) : null] }, result.seed));
|
|
91
90
|
}) }));
|
|
92
91
|
}
|
|
93
|
-
function
|
|
94
|
-
const match = jaml.match(new RegExp(`^${key}:\\s*(.+)$`, "m"));
|
|
95
|
-
return match?.[1]?.trim() || fallback;
|
|
96
|
-
}
|
|
97
|
-
function setRootValue(jaml, key, value) {
|
|
98
|
-
const line = `${key}: ${value}`;
|
|
99
|
-
const pattern = new RegExp(`^${key}:\\s*.*$`, "m");
|
|
100
|
-
if (pattern.test(jaml)) {
|
|
101
|
-
return jaml.replace(pattern, line);
|
|
102
|
-
}
|
|
103
|
-
const trimmed = jaml.trimEnd();
|
|
104
|
-
return trimmed.length > 0 ? `${line}\n${trimmed}` : line;
|
|
105
|
-
}
|
|
106
|
-
import { RunConfigModal } from "./RunConfigModal.js";
|
|
107
|
-
function DeckStakeSelector({ jaml, onChange, onSearch, }) {
|
|
108
|
-
const deck = readRootValue(jaml, "deck", "Red");
|
|
109
|
-
const stake = readRootValue(jaml, "stake", "White");
|
|
110
|
-
const [modalOpen, setModalOpen] = useState(false);
|
|
111
|
-
const handleApply = (nextDeck, nextStake) => {
|
|
112
|
-
let next = setRootValue(jaml, "deck", nextDeck);
|
|
113
|
-
next = setRootValue(next, "stake", nextStake);
|
|
114
|
-
onChange(next);
|
|
115
|
-
onSearch?.();
|
|
116
|
-
};
|
|
117
|
-
return (_jsxs(_Fragment, { children: [_jsx("button", { onClick: () => setModalOpen(true), className: "j-btn j-btn--red", style: { height: 32, padding: 0, borderRadius: 8, overflow: 'hidden' }, children: _jsxs("div", { className: "j-btn__face", style: { display: 'flex', alignItems: 'center', gap: 8, padding: '0 8px 0 4px', height: '100%' }, children: [_jsx(DeckSprite, { deck: deck, stake: stake, size: compactDeckSpriteSize }), _jsxs("span", { style: { fontFamily: "m6x11plus, monospace", fontSize: 14 }, children: [deck, " / ", stake] })] }) }), _jsx(RunConfigModal, { open: modalOpen, onClose: () => setModalOpen(false), deck: deck, stake: stake, onChange: handleApply })] }));
|
|
118
|
-
}
|
|
119
|
-
const compactDeckSpriteSize = 24;
|
|
120
|
-
export function JamlIde({ jaml, defaultJaml, onChange, defaultMode = "code", searchResults = [], className = "", style, title = "JAML IDE", subtitle = "Jimbo's Ante Markup Language", compactHeader = false, actions, codePlaceholder = "Enter JAML...", onSearch, isSearching = false, hideFooter = false, visualFilter, onVisualFilterChange, }) {
|
|
92
|
+
export function JamlIde({ jaml, defaultJaml, onChange, defaultMode = "code", searchResults = [], className = "", style, title = "JAML IDE", subtitle = "Jimbo's Ante Markup Language", compactHeader = false, actions, codePlaceholder = "Enter JAML...", onSearch, isSearching = false, onTestSeed, jimbolateResult = "idle", jimbolateError, visualFilter, onVisualFilterChange, }) {
|
|
121
93
|
const [mode, setMode] = useState(defaultMode);
|
|
122
94
|
const [internalText, setInternalText] = useState(jaml ?? defaultJaml ?? "");
|
|
123
95
|
const [lastJamlProp, setLastJamlProp] = useState(jaml);
|
|
@@ -217,5 +189,5 @@ export function JamlIde({ jaml, defaultJaml, onChange, defaultMode = "code", sea
|
|
|
217
189
|
padding: compactHeader ? "8px 10px" : "10px 14px",
|
|
218
190
|
borderBottom: `1px solid ${JimboColorOption.PANEL_EDGE}`,
|
|
219
191
|
background: JimboColorOption.TEAL_GREY,
|
|
220
|
-
}, children: [_jsxs("div", { children: [_jsx("div", { style: { fontSize: 16, fontWeight: "normal", fontFamily: "m6x11plus, monospace", color: JimboColorOption.GOLD_TEXT }, children: title }), subtitle ? _jsx("div", { style: { fontSize: 11, color:
|
|
192
|
+
}, children: [_jsxs("div", { children: [_jsx("div", { style: { fontSize: 16, fontWeight: "normal", fontFamily: "m6x11plus, monospace", color: JimboColorOption.GOLD_TEXT }, children: title }), subtitle ? _jsx("div", { style: { fontSize: 11, color: "rgba(255,255,255,0.6)" }, children: subtitle }) : null] }), actions && (_jsx("div", { style: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap", justifyContent: "flex-end" }, children: actions }))] }), _jsx(JamlIdeToolbar, { mode: mode, onModeChange: setMode, resultCount: results.length, onSearch: onSearch, isSearching: isSearching }), _jsxs("div", { style: { flex: 1, minHeight: 0, overflow: mode === "map" ? "hidden" : "auto", background: JimboColorOption.DARKEST }, children: [mode === "visual" ? (_jsx(JamlIdeVisual, { filter: activeFilter, onChange: handleVisualFilterChange, onAddClause: handleAddClause })) : null, mode === "code" ? (_jsx(JamlCodeEditor, { value: text, onChange: handleTextChange, placeholder: codePlaceholder })) : null, mode === "map" ? _jsx(JamlMapEditor, { onChange: handleTextChange }) : null, mode === "results" ? (_jsx("div", { style: { padding: 12 }, children: _jsx(ResultsView, { results: results, jaml: text }) })) : null, mode === "jimbolate" ? (_jsx(Jimbolate, { jaml: text, onTest: (seed) => onTestSeed?.(seed), result: jimbolateResult, error: jimbolateError })) : null] }), _jsx(JimboModal, { open: addZone !== null, onClose: handlePickerClose, children: addZone !== null && (pickerFlow === "category" ? (_jsx(CategoryMenu, { onSelect: (cat) => setPickerFlow(cat) })) : pickerFlow === "joker" ? (_jsx(JokerPicker, { onSelect: handlePickerSelect })) : (_jsx(CategoryPicker, { config: CATEGORY_CONFIG_MAP[pickerFlow], onSelect: handlePickerSelect }))) })] }));
|
|
221
193
|
}
|
|
@@ -6,18 +6,18 @@ import { JimboColorOption } from "../ui/tokens.js";
|
|
|
6
6
|
export function JamlIdeToolbar({ mode, onModeChange, resultCount = 0, className = "", onSearch, isSearching = false }) {
|
|
7
7
|
const tabs = [
|
|
8
8
|
{ id: "visual", label: "Visual" },
|
|
9
|
-
{ id: "code", label: "
|
|
9
|
+
{ id: "code", label: "JAML" },
|
|
10
10
|
{ id: "map", label: "Map" },
|
|
11
11
|
{ id: "results", label: resultCount > 0 ? `Results (${resultCount})` : "Results" },
|
|
12
|
+
{ id: "jimbolate", label: "Jimbolate" },
|
|
12
13
|
];
|
|
13
14
|
return (_jsxs("div", { className: className, style: {
|
|
14
|
-
display: "
|
|
15
|
-
gridTemplateColumns: onSearch ? "1fr auto 1fr" : "1fr",
|
|
15
|
+
display: "flex",
|
|
16
16
|
alignItems: "center",
|
|
17
17
|
gap: 8,
|
|
18
|
-
minWidth: 0,
|
|
19
18
|
padding: "10px 10px 6px",
|
|
20
19
|
borderBottom: `1px solid ${JimboColorOption.PANEL_EDGE}`,
|
|
21
20
|
background: JimboColorOption.DARKEST,
|
|
22
|
-
|
|
21
|
+
minWidth: 0,
|
|
22
|
+
}, children: [_jsx("div", { style: { flex: 1, minWidth: 0, paddingBottom: 3 }, children: _jsx(JimboTabs, { tabs: tabs, activeTab: mode, onTabChange: (id) => onModeChange(id) }) }), onSearch && (_jsx("div", { style: { flexShrink: 0 }, children: _jsx(JimboButton, { tone: isSearching ? "red" : "orange", size: "sm", onClick: onSearch, children: isSearching ? "Stop" : "Search" }) }))] }));
|
|
23
23
|
}
|
|
@@ -29,7 +29,7 @@ const GLOW_ANIMATION = `
|
|
|
29
29
|
100% { box-shadow: 0 0 0 1px var(--glow-color), 0 0 4px var(--glow-color); opacity: 0.8; }
|
|
30
30
|
}
|
|
31
31
|
`;
|
|
32
|
-
function ClausePill({ item,
|
|
32
|
+
function ClausePill({ item, glow, matchCount }) {
|
|
33
33
|
const isHit = matchCount > 0;
|
|
34
34
|
const hasData = matchCount !== undefined && matchCount >= 0;
|
|
35
35
|
return (_jsxs("div", { style: {
|
|
@@ -42,6 +42,7 @@ function ClausePill({ item, color, glow, matchCount }) {
|
|
|
42
42
|
padding: "3px 8px",
|
|
43
43
|
position: "relative",
|
|
44
44
|
opacity: isHit ? 1 : 0.6,
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
45
46
|
// @ts-ignore -- CSS custom property
|
|
46
47
|
"--glow-color": glow,
|
|
47
48
|
animation: isHit ? "j-glow-pulse 1.6s ease-in-out infinite" : "none",
|
|
@@ -63,41 +64,6 @@ function ClausePill({ item, color, glow, matchCount }) {
|
|
|
63
64
|
boxShadow: `0 1px 0 ${C.BLACK}`,
|
|
64
65
|
}, children: matchCount > 1 ? `x${matchCount}` : "✓" }))] }));
|
|
65
66
|
}
|
|
66
|
-
function VisualChip({ item, matchCount, compact }) {
|
|
67
|
-
const isHit = matchCount > 0;
|
|
68
|
-
const hasData = matchCount !== undefined;
|
|
69
|
-
const glow = ZONES[item.section].glow;
|
|
70
|
-
return (_jsxs("div", { style: {
|
|
71
|
-
display: "flex",
|
|
72
|
-
alignItems: "center",
|
|
73
|
-
gap: compact ? 3 : 6,
|
|
74
|
-
background: isHit ? `${glow}33` : C.DARKEST,
|
|
75
|
-
border: `2px solid ${isHit ? glow : C.PANEL_EDGE}`,
|
|
76
|
-
borderRadius: 4,
|
|
77
|
-
padding: compact ? "2px 4px" : "3px 8px",
|
|
78
|
-
position: "relative",
|
|
79
|
-
opacity: isHit ? 1 : 0.6,
|
|
80
|
-
// @ts-ignore
|
|
81
|
-
"--glow-color": glow,
|
|
82
|
-
animation: isHit ? "j-glow-pulse 1.6s ease-in-out infinite" : "none",
|
|
83
|
-
}, title: `${item.clauseKey}: ${item.value}${hasData ? ` (Found: ${matchCount})` : ""}`, children: [_jsx("style", { children: GLOW_ANIMATION }), _jsx("div", { style: { color: C.GREY, fontSize: 10, lineHeight: 1, padding: "0 2px" }, children: "\u22EE\u22EE" }), _jsx(JimboSprite, { name: item.value, sheet: SHEET_FOR_VISUAL[item.visualType], width: compact ? 20 : 26 }), _jsx("div", { style: {
|
|
84
|
-
fontSize: compact ? 9 : 10,
|
|
85
|
-
color: C.WHITE,
|
|
86
|
-
letterSpacing: 0.5,
|
|
87
|
-
textShadow: "1px 1px 0 rgba(0,0,0,.8)",
|
|
88
|
-
}, children: item.value }), isHit && (_jsx("div", { style: {
|
|
89
|
-
position: "absolute",
|
|
90
|
-
top: compact ? -4 : -6,
|
|
91
|
-
right: compact ? -4 : -6,
|
|
92
|
-
background: C.GREEN,
|
|
93
|
-
color: C.WHITE,
|
|
94
|
-
fontSize: 7,
|
|
95
|
-
padding: "1px 3px",
|
|
96
|
-
borderRadius: 3,
|
|
97
|
-
border: `1px solid ${C.BLACK}`,
|
|
98
|
-
boxShadow: `0 1px 0 ${C.BLACK}`,
|
|
99
|
-
}, children: matchCount > 1 ? `x${matchCount}` : "✓" }))] }));
|
|
100
|
-
}
|
|
101
67
|
function ZoneRail({ zone, items, matchMap, compact = false }) {
|
|
102
68
|
const meta = ZONES[zone];
|
|
103
69
|
return (_jsxs("div", { style: {
|
|
@@ -117,7 +83,7 @@ function ZoneRail({ zone, items, matchMap, compact = false }) {
|
|
|
117
83
|
// or "must: rareJoker: Blueprint". We try to match the item value and section.
|
|
118
84
|
const labelKey = `${item.section}: ${item.clauseKey}: ${item.value}`;
|
|
119
85
|
const count = matchMap[labelKey] ?? -1;
|
|
120
|
-
return (_jsx(ClausePill, { item: item,
|
|
86
|
+
return (_jsx(ClausePill, { item: item, glow: meta.glow, matchCount: count }, item.id));
|
|
121
87
|
})) })] }));
|
|
122
88
|
}
|
|
123
89
|
export function JamlMapPreview({ jaml, className = "", emptyMessage = "No visual JAML clauses found yet.", tallyColumns, tallyLabels, compact = false, }) {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface JimbolateProps {
|
|
2
|
+
jaml: string;
|
|
3
|
+
onTest: (seed: string) => void;
|
|
4
|
+
result: "idle" | "match" | "nomatch" | "running" | "error";
|
|
5
|
+
error?: string | null;
|
|
6
|
+
}
|
|
7
|
+
export declare function Jimbolate({ jaml, onTest, result, error }: JimbolateProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useRef } from "react";
|
|
4
|
+
import { JimboPanel, JimboButton } from "../ui/panel.js";
|
|
5
|
+
import { JimboText } from "../ui/jimboText.js";
|
|
6
|
+
import { JimboColorOption } from "../ui/tokens.js";
|
|
7
|
+
export function Jimbolate({ jaml, onTest, result, error }) {
|
|
8
|
+
const [seed, setSeed] = useState("");
|
|
9
|
+
const inputRef = useRef(null);
|
|
10
|
+
const handleTest = () => {
|
|
11
|
+
const s = seed.trim().toUpperCase();
|
|
12
|
+
if (!s)
|
|
13
|
+
return;
|
|
14
|
+
onTest(s);
|
|
15
|
+
};
|
|
16
|
+
return (_jsxs("div", { style: { padding: 10, display: "flex", flexDirection: "column", gap: 8 }, children: [_jsx(JimboPanel, { children: _jsxs("div", { style: { display: "flex", gap: 6 }, children: [_jsx("input", { ref: inputRef, className: "j-seed-input__field", type: "text", placeholder: "Enter seed...", value: seed, maxLength: 12, onChange: (e) => setSeed(e.target.value.toUpperCase()), onKeyDown: (e) => e.key === "Enter" && handleTest(), style: { flex: 1, fontSize: 15, padding: "6px 10px", letterSpacing: "0.1em", textTransform: "uppercase" } }), _jsx(JimboButton, { tone: result === "running" ? "red" : "orange", size: "sm", onClick: handleTest, disabled: !seed.trim() || !jaml.trim(), children: result === "running" ? "..." : "Test" })] }) }), result === "match" && (_jsxs(JimboPanel, { style: { background: `${JimboColorOption.GREEN_TEXT}22`, textAlign: "center" }, children: [_jsx(JimboText, { size: "xl", tone: "gold", style: { letterSpacing: 3, display: "block", marginBottom: 4 }, children: seed }), _jsx(JimboText, { size: "md", tone: "green", children: "MATCH" })] })), result === "nomatch" && (_jsxs(JimboPanel, { style: { textAlign: "center" }, children: [_jsx(JimboText, { size: "xl", tone: "grey", style: { letterSpacing: 3, display: "block", marginBottom: 4 }, children: seed }), _jsx(JimboText, { size: "md", tone: "red", children: "no match" })] })), result === "error" && (_jsx(JimboPanel, { children: _jsx(JimboText, { size: "xs", tone: "red", style: { display: "block", textAlign: "center" }, children: error ?? "Error" }) })), result === "idle" && !jaml.trim() && (_jsx(JimboPanel, { children: _jsx(JimboText, { size: "xs", tone: "grey", style: { display: "block", textAlign: "center" }, children: "Write a JAML filter in the JAML tab first" }) }))] }));
|
|
17
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface FilterItem {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
authorText?: string;
|
|
6
|
+
dateText?: string;
|
|
7
|
+
statsText?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface PaginatedFilterBrowserProps {
|
|
10
|
+
filters: FilterItem[];
|
|
11
|
+
itemsPerPage?: number;
|
|
12
|
+
onSelectFilter?: (filter: FilterItem) => void;
|
|
13
|
+
onMainAction?: (filter: FilterItem) => void;
|
|
14
|
+
onSecondaryAction?: (filter: FilterItem) => void;
|
|
15
|
+
onDeleteFilter?: (filter: FilterItem) => void;
|
|
16
|
+
mainActionText?: string;
|
|
17
|
+
secondaryActionText?: string;
|
|
18
|
+
showSecondary?: boolean;
|
|
19
|
+
showDelete?: boolean;
|
|
20
|
+
emptyText?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare function PaginatedFilterBrowser({ filters, itemsPerPage, // matching Balatro challenges layout pages
|
|
23
|
+
onSelectFilter, onMainAction, onSecondaryAction, onDeleteFilter, mainActionText, secondaryActionText, showSecondary, showDelete, emptyText, }: PaginatedFilterBrowserProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { JimboButton, JimboPanel } from "../ui/panel.js";
|
|
4
|
+
import { JimboText } from "../ui/jimboText.js";
|
|
5
|
+
import { JimboFlankNav } from "../ui/jimboFlankNav.js";
|
|
6
|
+
import { JimboColorOption } from "../ui/tokens.js";
|
|
7
|
+
const C = JimboColorOption;
|
|
8
|
+
export function PaginatedFilterBrowser({ filters, itemsPerPage = 120, // matching Balatro challenges layout pages
|
|
9
|
+
onSelectFilter, onMainAction, onSecondaryAction, onDeleteFilter, mainActionText = "SELECT", secondaryActionText = "EDIT", showSecondary = false, showDelete = false, emptyText = "No items found.", }) {
|
|
10
|
+
const [currentPage, setCurrentPage] = useState(0);
|
|
11
|
+
const [selectedId, setSelectedId] = useState(null);
|
|
12
|
+
const totalPages = Math.max(1, Math.ceil(filters.length / itemsPerPage));
|
|
13
|
+
// Bound current page just in case filters array shrinks
|
|
14
|
+
const safePage = Math.min(currentPage, totalPages - 1);
|
|
15
|
+
const pageFilters = filters.slice(safePage * itemsPerPage, (safePage + 1) * itemsPerPage);
|
|
16
|
+
const selectedFilter = filters.find((f) => f.id === selectedId) || null;
|
|
17
|
+
const handlePrevPage = () => setCurrentPage((p) => Math.max(0, p - 1));
|
|
18
|
+
const handleNextPage = () => setCurrentPage((p) => Math.min(totalPages - 1, p + 1));
|
|
19
|
+
return (_jsxs("div", { className: "j-flex-col j-gap-md", style: {
|
|
20
|
+
width: "100%",
|
|
21
|
+
height: "100%",
|
|
22
|
+
boxSizing: "border-box",
|
|
23
|
+
overflow: "hidden",
|
|
24
|
+
}, children: [_jsxs(JimboPanel, { style: { flex: 1, minHeight: 0, display: "flex", flexDirection: "column" }, children: [_jsxs("div", { style: { flex: 1, overflowY: "auto", position: "relative" }, className: "hide-scrollbar j-flex-col j-items-center j-gap-xs", children: [pageFilters.map((filter) => {
|
|
25
|
+
const isSelected = selectedId === filter.id;
|
|
26
|
+
return (_jsxs("div", { style: {
|
|
27
|
+
position: "relative",
|
|
28
|
+
width: "100%",
|
|
29
|
+
maxWidth: 240, // Matches filter-list-item MinWidth=210 approx
|
|
30
|
+
display: "flex",
|
|
31
|
+
justifyContent: "center",
|
|
32
|
+
}, children: [isSelected && (_jsx("div", { className: "j-animate-jimbo-bounce", style: {
|
|
33
|
+
position: "absolute",
|
|
34
|
+
left: -20, // push out to left
|
|
35
|
+
top: "50%",
|
|
36
|
+
transform: "translateY(-50%)",
|
|
37
|
+
width: 0,
|
|
38
|
+
height: 0,
|
|
39
|
+
borderTop: "8px solid transparent",
|
|
40
|
+
borderBottom: "8px solid transparent",
|
|
41
|
+
borderLeft: `12px solid ${C.GOLD}`, // Balatro usually uses gold/white for selection triangle
|
|
42
|
+
filter: `drop-shadow(2px 2px 2px rgba(0,0,0,0.5))`,
|
|
43
|
+
} })), _jsx("div", { style: { width: "100%" }, children: _jsx(JimboButton, { tone: isSelected ? "red" : "grey", size: "sm", style: { width: "100%" }, onClick: () => {
|
|
44
|
+
setSelectedId(filter.id);
|
|
45
|
+
onSelectFilter?.(filter);
|
|
46
|
+
}, children: filter.name }) })] }, filter.id));
|
|
47
|
+
}), pageFilters.length === 0 && (_jsx("div", { className: "j-p-md", children: _jsx(JimboText, { size: "sm", tone: "grey", className: "j-text-center", children: emptyText }) }))] }), _jsx("div", { className: "j-flex j-justify-center j-mt-md", style: { flexShrink: 0 }, children: _jsx(JimboFlankNav, { canPrev: safePage > 0, canNext: safePage < totalPages - 1, onPrev: handlePrevPage, onNext: handleNextPage, children: _jsx("div", { style: {
|
|
48
|
+
background: C.RED,
|
|
49
|
+
padding: "8px 24px",
|
|
50
|
+
borderRadius: 8,
|
|
51
|
+
minWidth: 100,
|
|
52
|
+
boxShadow: `inset 0 2px 4px rgba(255,255,255,0.2), 0 4px 8px rgba(0,0,0,0.4)`,
|
|
53
|
+
}, className: "j-flex j-justify-center j-items-center", children: _jsxs(JimboText, { size: "sm", tone: "white", className: "j-text-center", style: { textShadow: "1px 2px 2px rgba(0,0,0,0.5)" }, children: [safePage + 1, " / ", totalPages] }) }) }) })] }), _jsx(JimboPanel, { style: { flexShrink: 0, minHeight: 180, display: "flex", flexDirection: "column", justifyContent: "center" }, children: !selectedFilter ? (_jsx(JimboText, { size: "md", tone: "grey", className: "j-text-center", children: "Select an item to view details" })) : (_jsxs("div", { className: "j-flex-col j-gap-sm j-items-center", style: { width: "100%" }, children: [_jsx(JimboText, { size: "lg", tone: "gold", className: "j-text-center", children: selectedFilter.name }), _jsx(JimboText, { size: "sm", tone: "white", className: "j-text-center", children: selectedFilter.description }), _jsxs("div", { className: "j-flex-col j-gap-xs j-items-center j-mt-xs", style: { opacity: 0.7 }, children: [selectedFilter.authorText && _jsx(JimboText, { size: "xs", tone: "grey", children: selectedFilter.authorText }), selectedFilter.dateText && _jsx(JimboText, { size: "xs", tone: "grey", children: selectedFilter.dateText }), selectedFilter.statsText && _jsx(JimboText, { size: "xs", tone: "grey", children: selectedFilter.statsText })] }), _jsxs("div", { className: "j-flex j-gap-sm j-mt-md j-justify-center j-flex-wrap", children: [_jsx(JimboButton, { tone: "blue", size: "sm", onClick: () => onMainAction?.(selectedFilter), children: mainActionText }), showSecondary && onSecondaryAction && (_jsx(JimboButton, { tone: "orange", size: "sm", onClick: () => onSecondaryAction(selectedFilter), children: secondaryActionText })), showDelete && onDeleteFilter && (_jsx(JimboButton, { tone: "red", size: "sm", onClick: () => onDeleteFilter(selectedFilter), children: "DELETE" }))] })] })) })] }));
|
|
54
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React, { useState } from "react";
|
|
3
|
-
import { JimboModal } from "../ui/panel.js";
|
|
3
|
+
import { JimboModal, JimboButton } from "../ui/panel.js";
|
|
4
|
+
import { JimboText } from "../ui/jimboText.js";
|
|
4
5
|
import { DECK_OPTIONS, STAKE_OPTIONS } from "../lib/data/constants.js";
|
|
5
6
|
import { DeckSprite } from "./DeckSprite.js";
|
|
6
7
|
import { StakeSprite } from "../ui/sprites.js";
|
|
7
|
-
import { JimboColorOption } from "../ui/tokens.js";
|
|
8
8
|
const DECK_DESCRIPTIONS = {
|
|
9
9
|
"Red": "+1 discard every round",
|
|
10
10
|
"Blue": "+1 hand every round",
|
|
@@ -24,49 +24,21 @@ const DECK_DESCRIPTIONS = {
|
|
|
24
24
|
};
|
|
25
25
|
const STAKE_DESCRIPTIONS = {
|
|
26
26
|
"White": "Base Difficulty",
|
|
27
|
-
"Red": "Small Blind gives\nno reward money
|
|
28
|
-
"Green": "Required score scales\nfaster for each Ante
|
|
29
|
-
"Black": "Shop can have Jokers\nwith Eternal
|
|
30
|
-
"Blue": "-1 Discard
|
|
31
|
-
"Purple": "Required score scales\nfaster for each Ante
|
|
32
|
-
"Orange": "Shop can have Jokers\nwith Perishable
|
|
33
|
-
"Gold": "-1 hand size\nShop can have Jokers\nwith Rental
|
|
27
|
+
"Red": "Small Blind gives\nno reward money",
|
|
28
|
+
"Green": "Required score scales\nfaster for each Ante",
|
|
29
|
+
"Black": "Shop can have Jokers\nwith Eternal",
|
|
30
|
+
"Blue": "-1 Discard",
|
|
31
|
+
"Purple": "Required score scales\nfaster for each Ante",
|
|
32
|
+
"Orange": "Shop can have Jokers\nwith Perishable",
|
|
33
|
+
"Gold": "-1 hand size\nShop can have Jokers\nwith Rental",
|
|
34
34
|
};
|
|
35
|
-
function formatTextWithColors(text) {
|
|
36
|
-
// Hacky basic coloration for Balatro text
|
|
37
|
-
const parts = text.split(/(\d+|Spades|Hearts|Clubs|Diamonds|\$[\d]+|Eternal|Perishable|Rental|Chips|Mult)/g);
|
|
38
|
-
return parts.map((part, i) => {
|
|
39
|
-
let color = JimboColorOption.WHITE;
|
|
40
|
-
if (/^\d+$/.test(part))
|
|
41
|
-
color = JimboColorOption.RED;
|
|
42
|
-
else if (part === 'Spades')
|
|
43
|
-
color = JimboColorOption.BLUE; // Spades are typically blue in high contrast
|
|
44
|
-
else if (part === 'Hearts')
|
|
45
|
-
color = JimboColorOption.RED;
|
|
46
|
-
else if (part === 'Clubs')
|
|
47
|
-
color = JimboColorOption.GREEN_TEXT;
|
|
48
|
-
else if (part === 'Diamonds')
|
|
49
|
-
color = JimboColorOption.ORANGE_TEXT;
|
|
50
|
-
else if (part.startsWith('$'))
|
|
51
|
-
color = JimboColorOption.GOLD_TEXT;
|
|
52
|
-
else if (['Eternal', 'Perishable', 'Rental'].includes(part))
|
|
53
|
-
color = JimboColorOption.GOLD_TEXT; // Should be specific colours
|
|
54
|
-
else if (part === 'Chips')
|
|
55
|
-
color = JimboColorOption.BLUE;
|
|
56
|
-
else if (part === 'Mult')
|
|
57
|
-
color = JimboColorOption.RED;
|
|
58
|
-
if (color !== JimboColorOption.WHITE) {
|
|
59
|
-
return _jsx("span", { style: { color }, children: part }, i);
|
|
60
|
-
}
|
|
61
|
-
return _jsx("span", { children: part }, i);
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
35
|
export function RunConfigModal({ open, onClose, deck, stake, onChange, }) {
|
|
65
36
|
const [activeDeck, setActiveDeck] = useState(deck);
|
|
66
37
|
const [activeStake, setActiveStake] = useState(stake);
|
|
67
38
|
// Sync state if props change when opened
|
|
68
39
|
React.useEffect(() => {
|
|
69
40
|
if (open) {
|
|
41
|
+
// eslint-disable-next-line react-hooks/set-state-in-effect
|
|
70
42
|
setActiveDeck(deck);
|
|
71
43
|
setActiveStake(stake);
|
|
72
44
|
}
|
|
@@ -83,116 +55,5 @@ export function RunConfigModal({ open, onClose, deck, stake, onChange, }) {
|
|
|
83
55
|
onChange(activeDeck, activeStake);
|
|
84
56
|
onClose();
|
|
85
57
|
};
|
|
86
|
-
|
|
87
|
-
width: 32,
|
|
88
|
-
height: "100%",
|
|
89
|
-
borderRadius: 8,
|
|
90
|
-
background: JimboColorOption.RED,
|
|
91
|
-
border: `2px solid ${JimboColorOption.WHITE}`, // Should be dark edge with inner shadow but let's use standard red btn style
|
|
92
|
-
color: JimboColorOption.WHITE,
|
|
93
|
-
fontSize: 24,
|
|
94
|
-
fontFamily: "m6x11plus, monospace",
|
|
95
|
-
display: "flex",
|
|
96
|
-
alignItems: "center",
|
|
97
|
-
justifyContent: "center",
|
|
98
|
-
cursor: "pointer",
|
|
99
|
-
flexShrink: 0,
|
|
100
|
-
}, className: "j-btn j-btn--red" // piggyback on Jimbo button styles
|
|
101
|
-
, children: _jsx("div", { className: "j-btn__face", style: { padding: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: children }) }));
|
|
102
|
-
return (_jsx(JimboModal, { open: open, onClose: onClose, children: _jsxs("div", { style: {
|
|
103
|
-
width: 600,
|
|
104
|
-
maxWidth: "95vw",
|
|
105
|
-
background: JimboColorOption.TEAL_GREY, // A greenish-grey slate color
|
|
106
|
-
borderRadius: 16,
|
|
107
|
-
border: `3px solid ${JimboColorOption.BORDER_SILVER}`,
|
|
108
|
-
boxShadow: `inset 0 0 0 2px ${JimboColorOption.DARKEST}, 0 8px 16px rgba(0,0,0,0.5)`,
|
|
109
|
-
padding: "24px 20px",
|
|
110
|
-
display: "flex",
|
|
111
|
-
flexDirection: "column",
|
|
112
|
-
gap: 24,
|
|
113
|
-
position: "relative",
|
|
114
|
-
}, children: [_jsx("div", { style: {
|
|
115
|
-
position: "absolute",
|
|
116
|
-
top: -20,
|
|
117
|
-
left: 0,
|
|
118
|
-
right: 0,
|
|
119
|
-
display: "flex",
|
|
120
|
-
justifyContent: "center",
|
|
121
|
-
gap: 8,
|
|
122
|
-
}, children: _jsx("div", { className: "j-btn j-btn--red", style: { height: 36, pointerEvents: "none" }, children: _jsx("div", { className: "j-btn__face", style: { fontSize: 16, padding: "0 16px" }, children: "Seed Finder" }) }) }), _jsxs("div", { style: { display: "flex", height: 160, gap: 12 }, children: [_jsx(CarouselButton, { onClick: prevDeck, children: "<" }), _jsxs("div", { style: {
|
|
123
|
-
flex: 1,
|
|
124
|
-
background: JimboColorOption.DARK_GREY,
|
|
125
|
-
borderRadius: 12,
|
|
126
|
-
border: `2px solid ${JimboColorOption.PANEL_EDGE}`,
|
|
127
|
-
display: "flex",
|
|
128
|
-
alignItems: "center",
|
|
129
|
-
padding: "16px",
|
|
130
|
-
gap: 16,
|
|
131
|
-
}, children: [_jsx(DeckSprite, { deck: activeDeck, size: 100, style: { flexShrink: 0 } }), _jsxs("div", { style: { flex: 1, display: "flex", flexDirection: "column", alignItems: "center" }, children: [_jsxs("h2", { style: {
|
|
132
|
-
fontFamily: "m6x11plus, monospace",
|
|
133
|
-
fontSize: 28,
|
|
134
|
-
color: JimboColorOption.WHITE,
|
|
135
|
-
margin: "0 0 8px 0",
|
|
136
|
-
textShadow: `1px 1px 0 ${JimboColorOption.DARKEST}`,
|
|
137
|
-
}, children: [activeDeck, " Deck"] }), _jsx("div", { style: {
|
|
138
|
-
background: JimboColorOption.WHITE,
|
|
139
|
-
borderRadius: 8,
|
|
140
|
-
padding: "12px",
|
|
141
|
-
width: "100%",
|
|
142
|
-
minHeight: 80,
|
|
143
|
-
display: "flex",
|
|
144
|
-
flexDirection: "column",
|
|
145
|
-
alignItems: "center",
|
|
146
|
-
justifyContent: "center",
|
|
147
|
-
boxShadow: `inset 0 -2px 0 0 ${JimboColorOption.PANEL_EDGE}`,
|
|
148
|
-
}, children: _jsx("div", { style: {
|
|
149
|
-
fontFamily: "m6x11plus, monospace",
|
|
150
|
-
fontSize: 16,
|
|
151
|
-
color: JimboColorOption.DARKEST,
|
|
152
|
-
textAlign: "center",
|
|
153
|
-
whiteSpace: "pre-line",
|
|
154
|
-
lineHeight: 1.2,
|
|
155
|
-
}, children: formatTextWithColors(DECK_DESCRIPTIONS[activeDeck] || "Standard 52 card deck") }) })] }), _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 4, paddingRight: 4 }, children: [_jsx("div", { style: { width: 8, height: 8, borderRadius: 4, background: JimboColorOption.GREY } }), _jsx("div", { style: { width: 8, height: 8, borderRadius: 4, background: JimboColorOption.GREY } }), _jsx("div", { style: { width: 8, height: 8, borderRadius: 4, background: JimboColorOption.GREEN } }), _jsx("div", { style: { width: 8, height: 8, borderRadius: 4, background: JimboColorOption.RED } }), _jsx("div", { style: { width: 8, height: 8, borderRadius: 4, background: JimboColorOption.WHITE } })] })] }), _jsx(CarouselButton, { onClick: nextDeck, children: ">" })] }), _jsxs("div", { style: { display: "flex", height: 120, gap: 12 }, children: [_jsx(CarouselButton, { onClick: prevStake, children: "<" }), _jsxs("div", { style: {
|
|
156
|
-
flex: 1,
|
|
157
|
-
background: JimboColorOption.DARK_GREY,
|
|
158
|
-
borderRadius: 12,
|
|
159
|
-
border: `2px solid ${JimboColorOption.PANEL_EDGE}`,
|
|
160
|
-
display: "flex",
|
|
161
|
-
alignItems: "center",
|
|
162
|
-
padding: "12px 16px",
|
|
163
|
-
gap: 16,
|
|
164
|
-
position: "relative",
|
|
165
|
-
}, children: [_jsx("div", { style: {
|
|
166
|
-
position: 'absolute',
|
|
167
|
-
left: -14, // Cut out effect text
|
|
168
|
-
top: '50%',
|
|
169
|
-
transform: 'translateY(-50%) rotate(-90deg)',
|
|
170
|
-
fontFamily: "m6x11plus, monospace",
|
|
171
|
-
fontSize: 16,
|
|
172
|
-
color: JimboColorOption.GREY,
|
|
173
|
-
}, children: "Stake" }), _jsx("div", { style: { paddingLeft: 20 }, children: _jsx(StakeSprite, { stake: activeStake, width: 64, style: { flexShrink: 0 } }) }), _jsxs("div", { style: { flex: 1, display: "flex", flexDirection: "column", alignItems: "center" }, children: [_jsxs("h2", { style: {
|
|
174
|
-
fontFamily: "m6x11plus, monospace",
|
|
175
|
-
fontSize: 22,
|
|
176
|
-
color: JimboColorOption.WHITE,
|
|
177
|
-
margin: "0 0 6px 0",
|
|
178
|
-
textShadow: `1px 1px 0 ${JimboColorOption.DARKEST}`,
|
|
179
|
-
}, children: [activeStake, " Stake"] }), _jsx("div", { style: {
|
|
180
|
-
background: JimboColorOption.WHITE,
|
|
181
|
-
borderRadius: 8,
|
|
182
|
-
padding: "8px 12px",
|
|
183
|
-
width: "100%",
|
|
184
|
-
minHeight: 60,
|
|
185
|
-
display: "flex",
|
|
186
|
-
flexDirection: "column",
|
|
187
|
-
alignItems: "center",
|
|
188
|
-
justifyContent: "center",
|
|
189
|
-
boxShadow: `inset 0 -2px 0 0 ${JimboColorOption.PANEL_EDGE}`,
|
|
190
|
-
}, children: _jsx("div", { style: {
|
|
191
|
-
fontFamily: "m6x11plus, monospace",
|
|
192
|
-
fontSize: 14,
|
|
193
|
-
color: JimboColorOption.DARKEST,
|
|
194
|
-
textAlign: "center",
|
|
195
|
-
whiteSpace: "pre-line",
|
|
196
|
-
lineHeight: 1.2,
|
|
197
|
-
}, children: formatTextWithColors(STAKE_DESCRIPTIONS[activeStake] || "Base Difficulty") }) })] })] }), _jsx(CarouselButton, { onClick: nextStake, children: ">" })] }), _jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 12, marginTop: 8 }, children: [_jsx("button", { onClick: handleApply, className: "j-btn j-btn--blue j-btn--lg", style: { width: "80%", height: 50, fontSize: 24, padding: 0 }, children: _jsx("div", { className: "j-btn__face", style: { display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: "APPLY" }) }), _jsx("button", { onClick: onClose, className: "j-btn j-btn--orange j-btn--md", style: { width: "100%", height: 40, fontSize: 18, padding: 0 }, children: _jsx("div", { className: "j-btn__face", style: { display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: "Back" }) })] })] }) }));
|
|
58
|
+
return (_jsxs(JimboModal, { open: open, onClose: onClose, title: "Run Config", children: [_jsxs("div", { className: "j-flex j-items-center j-gap-sm", children: [_jsx(JimboButton, { tone: "red", size: "sm", onClick: prevDeck, children: "<" }), _jsxs("div", { className: "j-flex-col j-items-center j-gap-xs", style: { flex: 1 }, children: [_jsx(DeckSprite, { deck: activeDeck, size: 64 }), _jsxs(JimboText, { size: "md", tone: "white", children: [activeDeck, " Deck"] }), _jsx(JimboText, { size: "micro", tone: "grey", className: "j-text-center", style: { whiteSpace: "pre-line" }, children: DECK_DESCRIPTIONS[activeDeck] || "Standard 52 card deck" })] }), _jsx(JimboButton, { tone: "red", size: "sm", onClick: nextDeck, children: ">" })] }), _jsxs("div", { className: "j-flex j-items-center j-gap-sm", style: { marginTop: 8 }, children: [_jsx(JimboButton, { tone: "red", size: "sm", onClick: prevStake, children: "<" }), _jsxs("div", { className: "j-flex-col j-items-center j-gap-xs", style: { flex: 1 }, children: [_jsx(StakeSprite, { stake: activeStake, width: 48 }), _jsxs(JimboText, { size: "md", tone: "white", children: [activeStake, " Stake"] }), _jsx(JimboText, { size: "micro", tone: "grey", className: "j-text-center", style: { whiteSpace: "pre-line" }, children: STAKE_DESCRIPTIONS[activeStake] || "Base Difficulty" })] }), _jsx(JimboButton, { tone: "red", size: "sm", onClick: nextStake, children: ">" })] }), _jsxs("div", { className: "j-flex-col j-gap-sm", style: { marginTop: 8 }, children: [_jsx(JimboButton, { tone: "blue", size: "lg", fullWidth: true, onClick: handleApply, children: "Apply" }), _jsx(JimboButton, { tone: "orange", size: "lg", fullWidth: true, onClick: onClose, children: "Back" })] })] }));
|
|
198
59
|
}
|
|
@@ -20,9 +20,8 @@ export interface CategoryPickerConfig {
|
|
|
20
20
|
export interface CategoryPickerProps {
|
|
21
21
|
config: CategoryPickerConfig;
|
|
22
22
|
onSelect: (selection: SlotSelection) => void;
|
|
23
|
-
onCancel: () => void;
|
|
24
23
|
}
|
|
25
|
-
export declare function CategoryPicker({ config, onSelect
|
|
24
|
+
export declare function CategoryPicker({ config, onSelect }: CategoryPickerProps): import("react/jsx-runtime").JSX.Element;
|
|
26
25
|
export declare const VOUCHER_PICKER_CONFIG: CategoryPickerConfig;
|
|
27
26
|
export declare const TAG_PICKER_CONFIG: CategoryPickerConfig;
|
|
28
27
|
export declare const BOSS_PICKER_CONFIG: CategoryPickerConfig;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/* eslint-disable react-refresh/only-export-components */
|
|
3
4
|
import { useState, useCallback, useMemo } from "react";
|
|
4
5
|
import { JimboSprite } from "../../ui/sprites.js";
|
|
5
6
|
import { JimboColorOption } from "../../ui/tokens.js";
|
|
6
7
|
import { JimboText } from "../../ui/jimboText.js";
|
|
7
8
|
// ─── Component ───────────────────────────────────────────────────────────────
|
|
8
9
|
const C = JimboColorOption;
|
|
9
|
-
export function CategoryPicker({ config, onSelect
|
|
10
|
+
export function CategoryPicker({ config, onSelect }) {
|
|
10
11
|
const [search, setSearch] = useState("");
|
|
11
12
|
const filtered = useMemo(() => {
|
|
12
13
|
if (!search)
|