jaml-ui 0.6.1 → 0.7.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/LICENSE +21 -21
- package/README.md +135 -145
- package/dist/assets.js +13 -10
- package/dist/components/JamlIdeToolbar.js +2 -36
- package/dist/components/JamlIdeVisual.js +2 -2
- package/dist/hooks/loadMotelyWasm.d.ts +7 -0
- package/dist/hooks/loadMotelyWasm.js +16 -0
- package/dist/hooks/searchWorkerCode.d.ts +1 -0
- package/dist/hooks/searchWorkerCode.js +62 -0
- package/dist/hooks/useAnalyzer.d.ts +8 -0
- package/dist/hooks/useAnalyzer.js +72 -0
- package/dist/hooks/useSearch.d.ts +21 -0
- package/dist/hooks/useSearch.js +76 -0
- package/dist/ui/footer.js +5 -5
- package/dist/ui/panel.d.ts +6 -17
- package/dist/ui/panel.js +12 -47
- package/dist/ui/showcase.js +4 -4
- package/dist/ui/sprites.d.ts +2 -2
- package/dist/ui/sprites.js +1 -1
- package/package.json +107 -109
- package/assets/8BitDeck.png +0 -0
- package/assets/BlindChips.png +0 -0
- package/assets/Boosters.png +0 -0
- package/assets/Editions.png +0 -0
- package/assets/Enhancers.png +0 -0
- package/assets/Jokers.png +0 -0
- package/assets/Tarots.png +0 -0
- package/assets/Vouchers.png +0 -0
- package/assets/fonts/m6x11plusplus.otf +0 -0
- package/assets/stickers.png +0 -0
- package/assets/tags.png +0 -0
- package/dist/data/balatro-jokers.json +0 -1241
- package/dist/r3f/BalatroJokerMesh3D.d.ts +0 -8
- package/dist/r3f/BalatroJokerMesh3D.js +0 -98
- package/dist/r3f/BalatroJokerPreview3D.d.ts +0 -14
- package/dist/r3f/BalatroJokerPreview3D.js +0 -30
- package/dist/r3f/BalatroPlayingCard3D.d.ts +0 -22
- package/dist/r3f/BalatroPlayingCard3D.js +0 -62
- package/dist/r3f/cardConstants.d.ts +0 -16
- package/dist/r3f/cardConstants.js +0 -14
- package/dist/r3f/compositedAtlas.d.ts +0 -5
- package/dist/r3f/compositedAtlas.js +0 -56
- package/dist/r3f/gridUV.d.ts +0 -22
- package/dist/r3f/gridUV.js +0 -30
- package/dist/r3f/index.d.ts +0 -12
- package/dist/r3f/index.js +0 -13
- package/dist/r3f/jokerRegistry.d.ts +0 -28
- package/dist/r3f/jokerRegistry.js +0 -40
- package/dist/r3f/jokerTilt.d.ts +0 -8
- package/dist/r3f/jokerTilt.js +0 -41
- package/dist/r3f/magneticTilt.d.ts +0 -18
- package/dist/r3f/magneticTilt.js +0 -34
- package/dist/r3f/playingCardTypes.d.ts +0 -24
- package/dist/r3f/playingCardTypes.js +0 -32
- package/dist/r3f/playingCardVisuals.d.ts +0 -7
- package/dist/r3f/playingCardVisuals.js +0 -45
- package/dist/r3f/usePlayingCardTexture.d.ts +0 -7
- package/dist/r3f/usePlayingCardTexture.js +0 -92
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useState, useCallback, useRef, useEffect } from "react";
|
|
3
|
+
import { SEARCH_WORKER_CODE } from "./searchWorkerCode.js";
|
|
4
|
+
function createWorker(motelyWasmUrl) {
|
|
5
|
+
const blob = new Blob([SEARCH_WORKER_CODE], { type: "text/javascript" });
|
|
6
|
+
const blobUrl = URL.createObjectURL(blob);
|
|
7
|
+
const worker = new Worker(blobUrl);
|
|
8
|
+
worker.postMessage({ type: "init", url: motelyWasmUrl });
|
|
9
|
+
return worker;
|
|
10
|
+
}
|
|
11
|
+
export function useSearch(motelyWasmUrl) {
|
|
12
|
+
const [state, setState] = useState({
|
|
13
|
+
results: [],
|
|
14
|
+
totalSearched: 0n,
|
|
15
|
+
matchingSeeds: 0n,
|
|
16
|
+
status: "idle",
|
|
17
|
+
error: null,
|
|
18
|
+
});
|
|
19
|
+
const workerRef = useRef(null);
|
|
20
|
+
const readyRef = useRef(false);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
setState((s) => ({ ...s, status: "booting" }));
|
|
23
|
+
const worker = createWorker(motelyWasmUrl);
|
|
24
|
+
workerRef.current = worker;
|
|
25
|
+
readyRef.current = false;
|
|
26
|
+
worker.onmessage = (e) => {
|
|
27
|
+
const msg = e.data;
|
|
28
|
+
if (msg.type === "ready") {
|
|
29
|
+
readyRef.current = true;
|
|
30
|
+
setState((s) => s.status === "booting" ? { ...s, status: "idle" } : s);
|
|
31
|
+
}
|
|
32
|
+
else if (msg.type === "result") {
|
|
33
|
+
setState((s) => ({ ...s, results: [...s.results, { seed: msg.seed, score: msg.score }] }));
|
|
34
|
+
}
|
|
35
|
+
else if (msg.type === "progress") {
|
|
36
|
+
setState((s) => ({ ...s, totalSearched: BigInt(msg.searched), matchingSeeds: BigInt(msg.matching) }));
|
|
37
|
+
}
|
|
38
|
+
else if (msg.type === "complete") {
|
|
39
|
+
setState((s) => ({ ...s, status: msg.status === "Completed" ? "completed" : "error", error: msg.status !== "Completed" ? msg.status : null, totalSearched: BigInt(msg.searched), matchingSeeds: BigInt(msg.matched) }));
|
|
40
|
+
}
|
|
41
|
+
else if (msg.type === "cancelled") {
|
|
42
|
+
setState((s) => ({ ...s, status: "cancelled" }));
|
|
43
|
+
}
|
|
44
|
+
else if (msg.type === "error") {
|
|
45
|
+
setState((s) => ({ ...s, status: "error", error: msg.message }));
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
return () => {
|
|
49
|
+
worker.terminate();
|
|
50
|
+
workerRef.current = null;
|
|
51
|
+
};
|
|
52
|
+
}, [motelyWasmUrl]);
|
|
53
|
+
const start = useCallback((jaml, count) => {
|
|
54
|
+
const worker = workerRef.current;
|
|
55
|
+
if (!worker)
|
|
56
|
+
return;
|
|
57
|
+
setState({ results: [], totalSearched: 0n, matchingSeeds: 0n, status: "running", error: null });
|
|
58
|
+
if (readyRef.current) {
|
|
59
|
+
worker.postMessage({ type: "start", jaml, count });
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
const orig = worker.onmessage;
|
|
63
|
+
worker.onmessage = (e) => {
|
|
64
|
+
orig?.call(worker, e);
|
|
65
|
+
if (e.data.type === "ready") {
|
|
66
|
+
worker.onmessage = orig;
|
|
67
|
+
worker.postMessage({ type: "start", jaml, count });
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}, []);
|
|
72
|
+
const cancel = useCallback(() => {
|
|
73
|
+
workerRef.current?.postMessage({ type: "stop" });
|
|
74
|
+
}, []);
|
|
75
|
+
return { ...state, start, cancel };
|
|
76
|
+
}
|
package/dist/ui/footer.js
CHANGED
|
@@ -9,10 +9,10 @@ const SUITS = [
|
|
|
9
9
|
];
|
|
10
10
|
const CYCLE = '5s';
|
|
11
11
|
export function JimboBalatroFooter({ hidden = false, className = '' }) {
|
|
12
|
-
return (_jsxs("div", { className: ['fixed right-0 bottom-0 left-0 w-screen min-w-full transition-opacity duration-200', hidden ? 'pointer-events-none opacity-0' : 'opacity-100', className].filter(Boolean).join(' '), children: [_jsx("div", { style: { width: '100%', borderTop: '1px solid rgba(255,255,255,0.1)', background: 'rgba(0,0,0,0.9)', padding: '0 1rem 3px', textAlign: 'center' }, children: _jsxs("p", { style: { fontFamily: 'm6x11plus, monospace', fontSize: 'clamp(11px, 0.8vw + 8px, 14px)', display: 'flex', flexWrap: 'wrap', alignItems: 'center', justifyContent: 'center', gap: '0 0.5rem', color: 'white', margin: 0 }, children: [_jsx("span", { children: "Not affiliated with LocalThunk or PlayStack" }), _jsxs("span", { style: { display: 'inline-flex', alignItems: 'center', gap: '0.25rem' }, children: ["Made with", ' ', _jsx("span", { style: { position: 'relative', display: 'inline-block', width: '1.5em', height: '1em', verticalAlign: 'middle' }, children: SUITS.map(({ char, kf }) => (_jsx("span", { style: { position: 'absolute', inset: 0, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', opacity: 0, animationName: kf, animationDuration: CYCLE, animationDelay: '0s', animationIterationCount: 'infinite', animationTimingFunction: 'ease-out' }, children: char }, char))) }), ' ', "for the", ' ', _jsx("a", { href: "https://playbalatro.com", target: "_blank", rel: "noopener noreferrer", style: { color: JimboColorOption.GOLD, textDecoration: 'none' }, children: "Balatro" }), ' ', "community"] })] }) }), _jsx("style", { children: `
|
|
13
|
-
@keyframes jaml-heart { 0%{opacity:0;transform:scale(1)} 1%{opacity:1;transform:scale(1.45)} 3.5%{opacity:1;transform:scale(1)} 61.5%{opacity:1;transform:scale(1)} 62%{opacity:0} 100%{opacity:0} }
|
|
14
|
-
@keyframes jaml-spade { 0%,61.5%{opacity:0} 62%{opacity:1;transform:scale(1.45)} 64.5%{opacity:1;transform:scale(1)} 71.5%{opacity:1} 72%{opacity:0} 100%{opacity:0} }
|
|
15
|
-
@keyframes jaml-diamond { 0%,71.5%{opacity:0} 72%{opacity:1;transform:scale(1.45)} 74.5%{opacity:1;transform:scale(1)} 81.5%{opacity:1} 82%{opacity:0} 100%{opacity:0} }
|
|
16
|
-
@keyframes jaml-club { 0%,81.5%{opacity:0} 82%{opacity:1;transform:scale(1.45)} 84.5%{opacity:1;transform:scale(1)} 95%{opacity:1} 96%{opacity:0} 100%{opacity:0} }
|
|
12
|
+
return (_jsxs("div", { className: ['fixed right-0 bottom-0 left-0 w-screen min-w-full transition-opacity duration-200', hidden ? 'pointer-events-none opacity-0' : 'opacity-100', className].filter(Boolean).join(' '), children: [_jsx("div", { style: { width: '100%', borderTop: '1px solid rgba(255,255,255,0.1)', background: 'rgba(0,0,0,0.9)', padding: '0 1rem 3px', textAlign: 'center' }, children: _jsxs("p", { style: { fontFamily: 'm6x11plus, monospace', fontSize: 'clamp(11px, 0.8vw + 8px, 14px)', display: 'flex', flexWrap: 'wrap', alignItems: 'center', justifyContent: 'center', gap: '0 0.5rem', color: 'white', margin: 0 }, children: [_jsx("span", { children: "Not affiliated with LocalThunk or PlayStack" }), _jsxs("span", { style: { display: 'inline-flex', alignItems: 'center', gap: '0.25rem' }, children: ["Made with", ' ', _jsx("span", { style: { position: 'relative', display: 'inline-block', width: '1.5em', height: '1em', verticalAlign: 'middle' }, children: SUITS.map(({ char, kf }) => (_jsx("span", { style: { position: 'absolute', inset: 0, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', opacity: 0, animationName: kf, animationDuration: CYCLE, animationDelay: '0s', animationIterationCount: 'infinite', animationTimingFunction: 'ease-out' }, children: char }, char))) }), ' ', "for the", ' ', _jsx("a", { href: "https://playbalatro.com", target: "_blank", rel: "noopener noreferrer", style: { color: JimboColorOption.GOLD, textDecoration: 'none' }, children: "Balatro" }), ' ', "community"] })] }) }), _jsx("style", { children: `
|
|
13
|
+
@keyframes jaml-heart { 0%{opacity:0;transform:scale(1)} 1%{opacity:1;transform:scale(1.45)} 3.5%{opacity:1;transform:scale(1)} 61.5%{opacity:1;transform:scale(1)} 62%{opacity:0} 100%{opacity:0} }
|
|
14
|
+
@keyframes jaml-spade { 0%,61.5%{opacity:0} 62%{opacity:1;transform:scale(1.45)} 64.5%{opacity:1;transform:scale(1)} 71.5%{opacity:1} 72%{opacity:0} 100%{opacity:0} }
|
|
15
|
+
@keyframes jaml-diamond { 0%,71.5%{opacity:0} 72%{opacity:1;transform:scale(1.45)} 74.5%{opacity:1;transform:scale(1)} 81.5%{opacity:1} 82%{opacity:0} 100%{opacity:0} }
|
|
16
|
+
@keyframes jaml-club { 0%,81.5%{opacity:0} 82%{opacity:1;transform:scale(1.45)} 84.5%{opacity:1;transform:scale(1)} 95%{opacity:1} 96%{opacity:0} 100%{opacity:0} }
|
|
17
17
|
` })] }));
|
|
18
18
|
}
|
package/dist/ui/panel.d.ts
CHANGED
|
@@ -1,36 +1,25 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { type ButtonVariant } from './tokens.js';
|
|
3
2
|
export interface JimboPanelProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
4
3
|
sway?: boolean;
|
|
5
4
|
onBack?: () => void;
|
|
6
|
-
backLabel?: string;
|
|
7
5
|
hideBack?: boolean;
|
|
8
6
|
}
|
|
9
|
-
export declare const JimboPanel: React.MemoExoticComponent<({ children, className, sway, onBack,
|
|
7
|
+
export declare const JimboPanel: React.MemoExoticComponent<({ children, className, sway, onBack, hideBack, style, ...props }: JimboPanelProps) => import("react/jsx-runtime").JSX.Element>;
|
|
10
8
|
export interface JimboInnerPanelProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
11
9
|
}
|
|
12
10
|
export declare const JimboInnerPanel: React.MemoExoticComponent<({ children, className, style, ...props }: JimboInnerPanelProps) => import("react/jsx-runtime").JSX.Element>;
|
|
13
|
-
export
|
|
14
|
-
|
|
11
|
+
export type JimboTone = 'orange' | 'red' | 'blue' | 'green' | 'gold' | 'grey';
|
|
12
|
+
export interface JimboButtonProps {
|
|
13
|
+
tone?: JimboTone;
|
|
15
14
|
size?: 'xs' | 'sm' | 'md' | 'lg';
|
|
16
15
|
fullWidth?: boolean;
|
|
17
|
-
}
|
|
18
|
-
export declare function JimboButton({ children, variant, size, fullWidth, className, style, disabled, ...props }: JimboButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
-
export declare function JimboBackButton({ label, ...props }: Omit<JimboButtonProps, 'variant' | 'children'> & {
|
|
20
|
-
label?: string;
|
|
21
|
-
}): import("react/jsx-runtime").JSX.Element;
|
|
22
|
-
export type BalTone = 'orange' | 'red' | 'blue' | 'green' | 'gold' | 'grey';
|
|
23
|
-
export interface BalButtonProps {
|
|
24
|
-
tone?: BalTone;
|
|
25
|
-
size?: 'sm' | 'md' | 'lg';
|
|
26
|
-
fullWidth?: boolean;
|
|
27
16
|
disabled?: boolean;
|
|
28
17
|
onClick?: () => void;
|
|
29
18
|
style?: React.CSSProperties;
|
|
30
19
|
children?: React.ReactNode;
|
|
31
20
|
}
|
|
32
|
-
export declare function
|
|
33
|
-
export declare function
|
|
21
|
+
export declare function JimboButton({ tone, size, fullWidth, disabled, onClick, style, children, }: JimboButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
export declare function JimboBackButton({ onClick }: {
|
|
34
23
|
onClick?: () => void;
|
|
35
24
|
}): import("react/jsx-runtime").JSX.Element;
|
|
36
25
|
export interface JimboModalProps {
|
package/dist/ui/panel.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useEffect, useRef, memo } from 'react';
|
|
4
4
|
import { JimboColorOption, JIMBO_ANIMATIONS } from './tokens.js';
|
|
5
|
-
export const JimboPanel = memo(({ children, className = '', sway = false, onBack,
|
|
5
|
+
export const JimboPanel = memo(({ children, className = '', sway = false, onBack, hideBack = false, style, ...props }) => {
|
|
6
6
|
const panelRef = useRef(null);
|
|
7
7
|
useEffect(() => {
|
|
8
8
|
if (!sway || !panelRef.current)
|
|
@@ -23,51 +23,16 @@ export const JimboPanel = memo(({ children, className = '', sway = false, onBack
|
|
|
23
23
|
border: `3px solid ${JimboColorOption.BORDER_SILVER}`,
|
|
24
24
|
boxShadow: `0 3px 0 0 ${JimboColorOption.BORDER_SOUTH}`,
|
|
25
25
|
...style,
|
|
26
|
-
}, ...props, children: [_jsx("div", { className: "flex-1 overflow-auto", children: children }), onBack && !hideBack && (_jsx("div", { className: "mt-4 pt-2 shrink-0", children: _jsx(JimboBackButton, { onClick: onBack
|
|
26
|
+
}, ...props, children: [_jsx("div", { className: "flex-1 overflow-auto", children: children }), onBack && !hideBack && (_jsx("div", { className: "mt-4 pt-2 shrink-0", children: _jsx(JimboBackButton, { onClick: onBack }) }))] }));
|
|
27
27
|
});
|
|
28
28
|
JimboPanel.displayName = 'JimboPanel';
|
|
29
29
|
export const JimboInnerPanel = memo(({ children, className = '', style, ...props }) => (_jsx("div", { className: 'rounded-lg p-3 ' + className, style: { backgroundColor: JimboColorOption.INNER_BORDER, border: `2px solid ${JimboColorOption.PANEL_EDGE}`, ...style }, ...props, children: children })));
|
|
30
30
|
JimboInnerPanel.displayName = 'JimboInnerPanel';
|
|
31
|
-
// ───
|
|
32
|
-
|
|
33
|
-
primary: { bg: JimboColorOption.RED, hover: JimboColorOption.DARK_RED, text: '#fff' },
|
|
34
|
-
secondary: { bg: JimboColorOption.BLUE, hover: JimboColorOption.DARK_BLUE, text: '#fff' },
|
|
35
|
-
danger: { bg: JimboColorOption.RED, hover: JimboColorOption.DARK_RED, text: '#fff' },
|
|
36
|
-
back: { bg: JimboColorOption.ORANGE, hover: JimboColorOption.DARK_ORANGE, text: '#fff' },
|
|
37
|
-
ghost: { bg: 'transparent', hover: 'rgba(255,255,255,0.1)', text: '#fff' },
|
|
38
|
-
};
|
|
39
|
-
export function JimboButton({ children, variant = 'primary', size = 'md', fullWidth = false, className = '', style, disabled, ...props }) {
|
|
40
|
-
const [hovered, setHovered] = useState(false);
|
|
41
|
-
const [pressed, setPressed] = useState(false);
|
|
42
|
-
const c = VARIANT_COLORS[variant];
|
|
43
|
-
const pad = { xs: '0.2rem 0.5rem', sm: '0.25rem 0.75rem', md: '0.375rem 1rem', lg: '0.5rem 1.5rem' }[size];
|
|
44
|
-
return (_jsx("button", { disabled: disabled, onMouseEnter: () => { if (!disabled)
|
|
45
|
-
setHovered(true); }, onMouseLeave: () => { setHovered(false); setPressed(false); }, onMouseDown: () => { if (!disabled)
|
|
46
|
-
setPressed(true); }, onMouseUp: () => setPressed(false), className: className, style: {
|
|
47
|
-
fontFamily: 'm6x11plus, monospace',
|
|
48
|
-
backgroundColor: hovered ? c.hover : c.bg,
|
|
49
|
-
color: c.text,
|
|
50
|
-
padding: pad,
|
|
51
|
-
borderRadius: '0.5rem',
|
|
52
|
-
border: 'none',
|
|
53
|
-
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
54
|
-
width: fullWidth ? '100%' : undefined,
|
|
55
|
-
opacity: disabled ? 0.5 : 1,
|
|
56
|
-
transform: pressed ? 'translateY(3px)' : 'none',
|
|
57
|
-
boxShadow: pressed ? 'none' : '0 3px 0 0 rgba(0,0,0,0.5)',
|
|
58
|
-
textShadow: '1px 1px 0 rgba(0,0,0,0.8)',
|
|
59
|
-
userSelect: 'none',
|
|
60
|
-
...style,
|
|
61
|
-
}, ...props, children: children }));
|
|
62
|
-
}
|
|
63
|
-
export function JimboBackButton({ label = 'Back', ...props }) {
|
|
64
|
-
return _jsx(JimboButton, { variant: "back", size: "sm", fullWidth: true, ...props, children: label });
|
|
65
|
-
}
|
|
66
|
-
// ─── BalButton ────────────────────────────────────────────────────────────────
|
|
67
|
-
// Canonical Balatro-style flat 2D button.
|
|
31
|
+
// ─── JimboButton ──────────────────────────────────────────────────────────────
|
|
32
|
+
// Canonical flat 2D Balatro-style button.
|
|
68
33
|
// Two-layer: separate shadow div (3px south + 1px east) that disappears on press.
|
|
69
34
|
// Press translates the face onto the shadow. No gradients, no hover color change.
|
|
70
|
-
const
|
|
35
|
+
const JIMBO_TONE_PAIRS = {
|
|
71
36
|
orange: [JimboColorOption.ORANGE, JimboColorOption.DARK_ORANGE],
|
|
72
37
|
red: [JimboColorOption.RED, JimboColorOption.DARK_RED],
|
|
73
38
|
blue: [JimboColorOption.BLUE, JimboColorOption.DARK_BLUE],
|
|
@@ -75,11 +40,11 @@ const BAL_PAIRS = {
|
|
|
75
40
|
gold: [JimboColorOption.GOLD, '#8a6a1e'],
|
|
76
41
|
grey: [JimboColorOption.DARK_GREY, JimboColorOption.DARKEST],
|
|
77
42
|
};
|
|
78
|
-
export function
|
|
43
|
+
export function JimboButton({ tone = 'orange', size = 'md', fullWidth = false, disabled = false, onClick, style, children, }) {
|
|
79
44
|
const [pressed, setPressed] = useState(false);
|
|
80
|
-
const [fg, sh] =
|
|
81
|
-
const pad = size === 'sm' ? '4px 10px' : size === 'lg' ? '14px 18px' : '9px 14px';
|
|
82
|
-
const fs = size === 'sm' ? 12 : size === 'lg' ? 18 : 14;
|
|
45
|
+
const [fg, sh] = JIMBO_TONE_PAIRS[tone] ?? JIMBO_TONE_PAIRS.orange;
|
|
46
|
+
const pad = size === 'xs' ? '2px 8px' : size === 'sm' ? '4px 10px' : size === 'lg' ? '14px 18px' : '9px 14px';
|
|
47
|
+
const fs = size === 'xs' ? 10 : size === 'sm' ? 12 : size === 'lg' ? 18 : 14;
|
|
83
48
|
return (_jsxs("div", { onMouseDown: () => { if (!disabled)
|
|
84
49
|
setPressed(true); }, onMouseUp: () => setPressed(false), onMouseLeave: () => setPressed(false), onTouchStart: () => { if (!disabled)
|
|
85
50
|
setPressed(true); }, onTouchEnd: () => setPressed(false), onClick: () => { if (!disabled)
|
|
@@ -93,8 +58,8 @@ export function BalButton({ tone = 'orange', size = 'md', fullWidth = false, dis
|
|
|
93
58
|
textTransform: 'uppercase', lineHeight: 1.1,
|
|
94
59
|
}, children: children })] }));
|
|
95
60
|
}
|
|
96
|
-
export function
|
|
97
|
-
return (_jsx("div", { style: { display: 'flex', justifyContent: 'center', width: '100%', padding: '8px 10px 10px' }, children: _jsx(
|
|
61
|
+
export function JimboBackButton({ onClick }) {
|
|
62
|
+
return (_jsx("div", { style: { display: 'flex', justifyContent: 'center', width: '100%', padding: '8px 10px 10px' }, children: _jsx(JimboButton, { tone: "orange", size: "md", onClick: onClick, style: { width: '66.666%' }, children: "Back" }) }));
|
|
98
63
|
}
|
|
99
64
|
export function JimboModal({ children, open, onClose, title, className }) {
|
|
100
65
|
const [visible, setVisible] = useState(open);
|
|
@@ -112,5 +77,5 @@ export function JimboModal({ children, open, onClose, title, className }) {
|
|
|
112
77
|
}, [open]);
|
|
113
78
|
if (!visible)
|
|
114
79
|
return null;
|
|
115
|
-
return (_jsx("div", { style: { position: 'fixed', inset: 0, zIndex: 50, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '1rem', background: 'rgba(0,0,0,0.7)', opacity, transition: `opacity ${JIMBO_ANIMATIONS.MENU_SINK_DURATION}ms ease` }, onClick: onClose, children: _jsxs(JimboPanel, { sway: true, onBack: onClose,
|
|
80
|
+
return (_jsx("div", { style: { position: 'fixed', inset: 0, zIndex: 50, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '1rem', background: 'rgba(0,0,0,0.7)', opacity, transition: `opacity ${JIMBO_ANIMATIONS.MENU_SINK_DURATION}ms ease` }, onClick: onClose, children: _jsxs(JimboPanel, { sway: true, onBack: onClose, className: 'w-full flex flex-col max-h-[90vh] ' + (className ?? 'max-w-lg'), onClick: (e) => e.stopPropagation(), children: [title && _jsx("h2", { style: { fontFamily: 'm6x11plus, monospace', color: '#fff', textAlign: 'center', margin: '0 0 1rem', fontSize: '1.25rem' }, children: title }), children] }) }));
|
|
116
81
|
}
|
package/dist/ui/showcase.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { JimboColorOption } from './tokens.js';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { JimboButton } from './panel.js';
|
|
5
|
+
import { JimboSprite } from './sprites.js';
|
|
6
6
|
const TONE_COLOR = {
|
|
7
7
|
blue: JimboColorOption.BLUE,
|
|
8
8
|
red: JimboColorOption.RED,
|
|
@@ -34,7 +34,7 @@ export function Showcase({ hotFilters = [], recentFinds = [], stats = DEFAULT_ST
|
|
|
34
34
|
background: C.DARK_GREY, borderRadius: 6, padding: 10,
|
|
35
35
|
border: `2px solid ${tColor}`, boxShadow: `0 2px 0 ${C.BLACK}`,
|
|
36
36
|
display: 'flex', alignItems: 'center', gap: 10, cursor: 'pointer',
|
|
37
|
-
}, children: [_jsx("div", { style: { display: 'flex', gap: 2 }, children: f.sample.map((name, j) => (_jsx("div", { style: { width: 30, height: 40, display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: _jsx(
|
|
37
|
+
}, children: [_jsx("div", { style: { display: 'flex', gap: 2 }, children: f.sample.map((name, j) => (_jsx("div", { style: { width: 30, height: 40, display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: _jsx(JimboSprite, { name: name, width: 28 }) }, j))) }), _jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [_jsx("div", { style: {
|
|
38
38
|
fontSize: 13, color: C.WHITE, letterSpacing: 1,
|
|
39
39
|
textShadow: '1px 1px 0 rgba(0,0,0,.8)',
|
|
40
40
|
overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
|
|
@@ -50,5 +50,5 @@ export function Showcase({ hotFilters = [], recentFinds = [], stats = DEFAULT_ST
|
|
|
50
50
|
}, children: recentFinds.length === 0 ? (_jsx("div", { style: { color: C.GREY }, children: "No recent finds yet." })) : recentFinds.map((r, i) => (_jsxs("div", { children: [_jsx("span", { style: { color: C.GOLD_TEXT }, children: r.seed }), ' · ', r.filterName, r.score > 0 && _jsxs("span", { style: { color: C.GREEN_TEXT }, children: [" +", r.score] })] }, i))) }), _jsx("div", { style: { height: 16 } })] }), _jsxs("div", { style: {
|
|
51
51
|
padding: '8px 10px 10px', borderTop: `2px solid ${C.BLACK}`, background: C.DARK_GREY,
|
|
52
52
|
display: 'flex', flexDirection: 'column', gap: 6,
|
|
53
|
-
}, children: [_jsx(
|
|
53
|
+
}, children: [_jsx(JimboButton, { tone: "green", fullWidth: true, size: "md", onClick: onNewSearch, children: "New Search" }), _jsx(JimboButton, { tone: "blue", fullWidth: true, size: "md", onClick: onBrowseFilters, children: "Browse Filters" }), _jsx(JimboButton, { tone: "orange", fullWidth: true, size: "md", onClick: onBack, children: "Back" })] })] }));
|
|
54
54
|
}
|
package/dist/ui/sprites.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { type SpriteSheetType } from '../sprites/spriteMapper.js';
|
|
3
|
-
export interface
|
|
3
|
+
export interface JimboSpriteProps {
|
|
4
4
|
name: string;
|
|
5
5
|
sheet?: SpriteSheetType;
|
|
6
6
|
width?: number;
|
|
7
7
|
height?: number;
|
|
8
8
|
style?: React.CSSProperties;
|
|
9
9
|
}
|
|
10
|
-
export declare function
|
|
10
|
+
export declare function JimboSprite({ name, sheet, width, height, style }: JimboSpriteProps): import("react/jsx-runtime").JSX.Element | null;
|
package/dist/ui/sprites.js
CHANGED
|
@@ -12,7 +12,7 @@ const SHEET_META = {
|
|
|
12
12
|
Enhancers: { cols: 7, rows: 5, assetKey: 'enhancers' },
|
|
13
13
|
Editions: { cols: 5, rows: 1, assetKey: 'editions' },
|
|
14
14
|
};
|
|
15
|
-
export function
|
|
15
|
+
export function JimboSprite({ name, sheet, width = 40, height, style }) {
|
|
16
16
|
const sprite = getSpriteData(name);
|
|
17
17
|
const resolvedSheet = sheet ?? sprite?.type ?? 'Jokers';
|
|
18
18
|
const meta = SHEET_META[resolvedSheet];
|
package/package.json
CHANGED
|
@@ -1,109 +1,107 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "jaml-ui",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Balatro rendering components, sprite metadata, and optional Motely helpers for React apps.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "./dist/index.js",
|
|
7
|
-
"types": "./dist/index.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"types": "./dist/index.d.ts",
|
|
11
|
-
"import": "./dist/index.js"
|
|
12
|
-
},
|
|
13
|
-
"./core": {
|
|
14
|
-
"types": "./dist/core.d.ts",
|
|
15
|
-
"import": "./dist/core.js"
|
|
16
|
-
},
|
|
17
|
-
"./motely": {
|
|
18
|
-
"types": "./dist/motely.d.ts",
|
|
19
|
-
"import": "./dist/motely.js"
|
|
20
|
-
},
|
|
21
|
-
"./ui": {
|
|
22
|
-
"types": "./dist/ui.d.ts",
|
|
23
|
-
"import": "./dist/ui.js"
|
|
24
|
-
},
|
|
25
|
-
"./r3f": {
|
|
26
|
-
"types": "./dist/r3f.d.ts",
|
|
27
|
-
"import": "./dist/r3f.js"
|
|
28
|
-
},
|
|
29
|
-
"./
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
"
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"react": "
|
|
75
|
-
"
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
"@react
|
|
98
|
-
"@react-
|
|
99
|
-
"@types/
|
|
100
|
-
"
|
|
101
|
-
"
|
|
102
|
-
"
|
|
103
|
-
"react": "^
|
|
104
|
-
"
|
|
105
|
-
"
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "jaml-ui",
|
|
3
|
+
"version": "0.7.1",
|
|
4
|
+
"description": "Balatro rendering components, sprite metadata, and optional Motely helpers for React apps.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./core": {
|
|
14
|
+
"types": "./dist/core.d.ts",
|
|
15
|
+
"import": "./dist/core.js"
|
|
16
|
+
},
|
|
17
|
+
"./motely": {
|
|
18
|
+
"types": "./dist/motely.d.ts",
|
|
19
|
+
"import": "./dist/motely.js"
|
|
20
|
+
},
|
|
21
|
+
"./ui": {
|
|
22
|
+
"types": "./dist/ui.d.ts",
|
|
23
|
+
"import": "./dist/ui.js"
|
|
24
|
+
},
|
|
25
|
+
"./r3f": {
|
|
26
|
+
"types": "./dist/r3f.d.ts",
|
|
27
|
+
"import": "./dist/r3f.js"
|
|
28
|
+
},
|
|
29
|
+
"./package.json": "./package.json"
|
|
30
|
+
},
|
|
31
|
+
"sideEffects": false,
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"README.md",
|
|
35
|
+
"LICENSE"
|
|
36
|
+
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsc --pretty false",
|
|
39
|
+
"dev": "tsc --watch",
|
|
40
|
+
"typecheck": "tsc --noEmit --pretty false",
|
|
41
|
+
"prepack": "npm run build"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18"
|
|
45
|
+
},
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
},
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "https://github.com/OptimusPi/jaml-ui"
|
|
52
|
+
},
|
|
53
|
+
"homepage": "https://github.com/OptimusPi/jaml-ui#readme",
|
|
54
|
+
"bugs": {
|
|
55
|
+
"url": "https://github.com/OptimusPi/jaml-ui/issues"
|
|
56
|
+
},
|
|
57
|
+
"keywords": [
|
|
58
|
+
"balatro",
|
|
59
|
+
"jaml",
|
|
60
|
+
"motely",
|
|
61
|
+
"seed",
|
|
62
|
+
"card",
|
|
63
|
+
"sprite",
|
|
64
|
+
"ui"
|
|
65
|
+
],
|
|
66
|
+
"author": "pifreak",
|
|
67
|
+
"license": "MIT",
|
|
68
|
+
"peerDependencies": {
|
|
69
|
+
"@react-spring/three": ">=9.0.0",
|
|
70
|
+
"@react-three/fiber": ">=8.0.0",
|
|
71
|
+
"motely-wasm": "^10.2.0 || ^11.0.0 || ^12.0.0",
|
|
72
|
+
"react": "^18.2.0 || ^19.0.0",
|
|
73
|
+
"react-dom": "^18.2.0 || ^19.0.0",
|
|
74
|
+
"react-icons": ">=5.0.0",
|
|
75
|
+
"three": ">=0.150.0"
|
|
76
|
+
},
|
|
77
|
+
"peerDependenciesMeta": {
|
|
78
|
+
"@react-spring/three": {
|
|
79
|
+
"optional": true
|
|
80
|
+
},
|
|
81
|
+
"@react-three/fiber": {
|
|
82
|
+
"optional": true
|
|
83
|
+
},
|
|
84
|
+
"motely-wasm": {
|
|
85
|
+
"optional": true
|
|
86
|
+
},
|
|
87
|
+
"react-icons": {
|
|
88
|
+
"optional": true
|
|
89
|
+
},
|
|
90
|
+
"three": {
|
|
91
|
+
"optional": true
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
"devDependencies": {
|
|
95
|
+
"@react-spring/three": "^10.0.3",
|
|
96
|
+
"@react-three/fiber": "^9.6.0",
|
|
97
|
+
"@types/react": "^19.2.14",
|
|
98
|
+
"@types/react-dom": "^19.2.3",
|
|
99
|
+
"@types/three": "^0.184.0",
|
|
100
|
+
"motely-wasm": "^12.0.0",
|
|
101
|
+
"react": "^19.2.4",
|
|
102
|
+
"react-dom": "^19.2.4",
|
|
103
|
+
"react-icons": "^5.6.0",
|
|
104
|
+
"three": "^0.184.0",
|
|
105
|
+
"typescript": "^5.9.3"
|
|
106
|
+
}
|
|
107
|
+
}
|
package/assets/8BitDeck.png
DELETED
|
Binary file
|
package/assets/BlindChips.png
DELETED
|
Binary file
|
package/assets/Boosters.png
DELETED
|
Binary file
|
package/assets/Editions.png
DELETED
|
Binary file
|
package/assets/Enhancers.png
DELETED
|
Binary file
|
package/assets/Jokers.png
DELETED
|
Binary file
|
package/assets/Tarots.png
DELETED
|
Binary file
|
package/assets/Vouchers.png
DELETED
|
Binary file
|
|
Binary file
|
package/assets/stickers.png
DELETED
|
Binary file
|
package/assets/tags.png
DELETED
|
Binary file
|