jaml-ui 0.24.20 → 0.25.2
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 +0 -13
- package/assets/WeeJokerExampleDAilyGame.png +0 -0
- package/assets/balatro-stake-chips.png +0 -0
- package/dist/assets.d.ts +1 -2
- package/dist/chunks/Layer-BBPJFHfs.js +17 -0
- package/dist/chunks/Layer-BBPJFHfs.js.map +1 -0
- package/dist/chunks/assets-RWUiFSTc.js +37 -0
- package/dist/chunks/assets-RWUiFSTc.js.map +1 -0
- package/dist/chunks/motelyItemDecoder-CueyZ0XD.js +6039 -0
- package/dist/chunks/motelyItemDecoder-CueyZ0XD.js.map +1 -0
- package/dist/chunks/spriteMapper-CFjN0_TV.js +2415 -0
- package/dist/chunks/spriteMapper-CFjN0_TV.js.map +1 -0
- package/dist/chunks/tokens-B65Fzble.js +57 -0
- package/dist/chunks/tokens-B65Fzble.js.map +1 -0
- package/dist/chunks/ui-5cBy3zAm.js +1387 -0
- package/dist/chunks/ui-5cBy3zAm.js.map +1 -0
- package/dist/components/AnalyzerExplorer.d.ts +1 -1
- package/dist/components/CardFan.d.ts +1 -1
- package/dist/components/CardList.d.ts +1 -1
- package/dist/components/DeckSprite.d.ts +1 -1
- package/dist/components/JamlAestheticSelector.d.ts +1 -1
- package/dist/components/JamlAnalyzerFullscreen.d.ts +5 -5
- package/dist/components/JamlCurator.d.ts +1 -6
- package/dist/components/JamlIde.d.ts +5 -5
- package/dist/components/JamlSeedInput.d.ts +1 -1
- package/dist/components/JamlSpeedometer.d.ts +1 -1
- package/dist/components/MotelyVersionBadge.d.ts +1 -1
- package/dist/components/Standardcard.d.ts +1 -1
- package/dist/components/jamlMap/CategoryPicker.d.ts +3 -3
- package/dist/components/jamlMap/JamlMapEditor.d.ts +1 -1
- package/dist/components/jamlMap/JokerPicker.d.ts +1 -1
- package/dist/components/jamlMap/MysterySlot.d.ts +2 -2
- package/dist/components/jamlMap/index.d.ts +4 -4
- package/dist/core.d.ts +5 -5
- package/dist/core.js +27 -5
- package/dist/core.js.map +1 -0
- package/dist/decode/motelyItemDecoder.d.ts +0 -10
- package/dist/decode/motelySprite.d.ts +1 -1
- package/dist/fonts/m6x11plus.otf +0 -0
- package/dist/hooks/analyzerStreamRegistry.d.ts +2 -2
- package/dist/hooks/useAnalyzer.d.ts +3 -3
- package/dist/hooks/useSearch.d.ts +2 -2
- package/dist/index.d.ts +29 -31
- package/dist/index.js +16721 -34
- package/dist/index.js.map +1 -0
- package/dist/lib/const.d.ts +2 -2
- package/dist/lib/hooks/useDragScroll.d.ts +1 -1
- package/dist/lib/hooks/useJamlFilter.d.ts +2 -2
- package/dist/lib/hooks/useSeedAnalyzer.d.ts +2 -2
- package/dist/lib/utils.d.ts +1 -1
- package/dist/motely.d.ts +4 -3
- package/dist/motely.js +65 -3
- package/dist/motely.js.map +1 -0
- package/dist/motelyBoot.d.ts +2 -0
- package/dist/motelyDisplay.d.ts +0 -2
- package/dist/r3f/Card3D.d.ts +2 -2
- package/dist/r3f/JimboBillboard.d.ts +1 -1
- package/dist/r3f.js +235 -3
- package/dist/r3f.js.map +1 -0
- package/dist/render/CanvasRenderer.d.ts +1 -1
- package/dist/sprites/spriteData.d.ts +1 -6
- package/dist/sprites/spriteMapper.d.ts +1 -1
- package/dist/ui/JimboBadge.d.ts +1 -1
- package/dist/ui/JimboFloating.d.ts +1 -1
- package/dist/ui/JimboIconButton.d.ts +1 -1
- package/dist/ui/JimboSelect.d.ts +1 -1
- package/dist/ui/footer.d.ts +2 -3
- package/dist/ui/hooks.d.ts +1 -1
- package/dist/ui/ide/DeckSprite.d.ts +1 -1
- package/dist/ui/jimbo.css +2 -1856
- package/dist/ui/jimboApp.d.ts +1 -1
- package/dist/ui/jimboFilterBar.d.ts +1 -1
- package/dist/ui/jimboFlankNav.d.ts +1 -1
- package/dist/ui/jimboInfoCard.d.ts +1 -1
- package/dist/ui/jimboInset.d.ts +1 -1
- package/dist/ui/jimboStatGrid.d.ts +1 -1
- package/dist/ui/jimboText.d.ts +1 -1
- package/dist/ui/jimboTooltip.d.ts +2 -2
- package/dist/ui/mascot/SeedMascot.d.ts +2 -2
- package/dist/ui/panel.d.ts +1 -1
- package/dist/ui/radial/RadialBadge.d.ts +1 -2
- package/dist/ui/radial/RadialButton.d.ts +1 -2
- package/dist/ui/radial/RadialMenu.d.ts +2 -2
- package/dist/ui/radial/RadialPill.d.ts +1 -2
- package/dist/ui/radial/index.d.ts +16 -16
- package/dist/ui/radial/radialMenuStore.d.ts +1 -1
- package/dist/ui/showcase.d.ts +1 -1
- package/dist/ui/sprites.d.ts +2 -2
- package/dist/ui.d.ts +0 -1
- package/dist/ui.js +3 -36
- package/dist/utils/gameCardUtils.d.ts +1 -1
- package/dist/utils/jamlVisualFilter.d.ts +1 -7
- package/package.json +13 -25
- package/dist/assets.js +0 -48
- package/dist/components/AnalyzerExplorer.js +0 -391
- package/dist/components/CardFan.js +0 -80
- package/dist/components/CardList.js +0 -5
- package/dist/components/DeckSprite.js +0 -75
- package/dist/components/GameCard.js +0 -355
- package/dist/components/JamlAestheticSelector.js +0 -22
- package/dist/components/JamlAnalyzerFullscreen.js +0 -263
- package/dist/components/JamlCodeEditor.js +0 -137
- package/dist/components/JamlCurator.js +0 -64
- package/dist/components/JamlCurator.stories.d.ts +0 -6
- package/dist/components/JamlCurator.stories.js +0 -14
- package/dist/components/JamlIde.js +0 -193
- package/dist/components/JamlIdeToolbar.js +0 -23
- package/dist/components/JamlIdeVisual.js +0 -218
- package/dist/components/JamlMapPreview.js +0 -121
- package/dist/components/JamlSeedInput.js +0 -26
- package/dist/components/JamlSpeedometer.js +0 -70
- package/dist/components/Jimbolate.js +0 -17
- package/dist/components/MotelyVersionBadge.js +0 -19
- package/dist/components/PaginatedFilterBrowser.js +0 -54
- package/dist/components/RunConfigModal.js +0 -59
- package/dist/components/Standardcard.js +0 -80
- package/dist/components/jamlMap/CategoryPicker.js +0 -135
- package/dist/components/jamlMap/JamlMapEditor.js +0 -304
- package/dist/components/jamlMap/JamlMapEditor.stories.d.ts +0 -7
- package/dist/components/jamlMap/JamlMapEditor.stories.js +0 -26
- package/dist/components/jamlMap/JamlMapEditorDemo.d.ts +0 -8
- package/dist/components/jamlMap/JamlMapEditorDemo.js +0 -323
- package/dist/components/jamlMap/JokerPicker.js +0 -113
- package/dist/components/jamlMap/MysterySlot.js +0 -128
- package/dist/components/jamlMap/MysterySlot.stories.d.ts +0 -7
- package/dist/components/jamlMap/MysterySlot.stories.js +0 -31
- package/dist/components/jamlMap/index.js +0 -4
- package/dist/decode/motelyItemDecoder.js +0 -164
- package/dist/decode/motelySprite.js +0 -84
- package/dist/hooks/analyzerStreamRegistry.js +0 -96
- package/dist/hooks/searchWorker.d.ts +0 -1
- package/dist/hooks/searchWorker.js +0 -119
- package/dist/hooks/searchWorkerCode.d.ts +0 -1
- package/dist/hooks/searchWorkerCode.js +0 -85
- package/dist/hooks/useAnalyzer.js +0 -91
- package/dist/hooks/useIntersectionObserver.js +0 -52
- package/dist/hooks/useSearch.js +0 -161
- package/dist/hooks/useShopStream.js +0 -85
- package/dist/lib/SpriteMapper.js +0 -48
- package/dist/lib/cardParser.js +0 -67
- package/dist/lib/classes/BuyMetaData.js +0 -1
- package/dist/lib/config.js +0 -15
- package/dist/lib/const.js +0 -521
- package/dist/lib/data/constants.js +0 -14
- package/dist/lib/hooks/useDragScroll.js +0 -48
- package/dist/lib/hooks/useJamlFilter.js +0 -219
- package/dist/lib/hooks/useSeedAnalyzer.js +0 -50
- package/dist/lib/jaml/jamlCompletion.js +0 -13
- package/dist/lib/jaml/jamlData.js +0 -6
- package/dist/lib/jaml/jamlObjectives.js +0 -97
- package/dist/lib/jaml/jamlParser.js +0 -47
- package/dist/lib/jaml/jamlPresets.js +0 -61
- package/dist/lib/jaml/jamlSchema.js +0 -91
- package/dist/lib/parseDailyRitual.js +0 -70
- package/dist/lib/tts/getRevealPos.js +0 -16
- package/dist/lib/tts/splitTtsDisplay.js +0 -35
- package/dist/lib/types.js +0 -1
- package/dist/lib/utils.js +0 -5
- package/dist/motelyDisplay.js +0 -59
- package/dist/r3f/Card3D.js +0 -72
- package/dist/r3f/JimboBillboard.js +0 -32
- package/dist/r3f/JimboText3D.js +0 -8
- package/dist/render/CanvasRenderer.js +0 -11
- package/dist/render/Layer.js +0 -18
- package/dist/sprites/spriteData.js +0 -100
- package/dist/sprites/spriteMapper.js +0 -75
- package/dist/stories/Button.d.ts +0 -15
- package/dist/stories/Button.js +0 -7
- package/dist/stories/Button.stories.d.ts +0 -24
- package/dist/stories/Button.stories.js +0 -50
- package/dist/stories/Header.d.ts +0 -12
- package/dist/stories/Header.js +0 -4
- package/dist/stories/Header.stories.d.ts +0 -18
- package/dist/stories/Header.stories.js +0 -26
- package/dist/stories/Page.d.ts +0 -3
- package/dist/stories/Page.js +0 -8
- package/dist/stories/Page.stories.d.ts +0 -12
- package/dist/stories/Page.stories.js +0 -24
- package/dist/ui/Jimbo.stories.d.ts +0 -7
- package/dist/ui/Jimbo.stories.js +0 -28
- package/dist/ui/JimboBadge.js +0 -8
- package/dist/ui/JimboFloating.js +0 -17
- package/dist/ui/JimboIconButton.js +0 -28
- package/dist/ui/JimboInputModal.js +0 -66
- package/dist/ui/JimboSelect.js +0 -43
- package/dist/ui/JimboToggleList.js +0 -5
- package/dist/ui/PanelSplitter.js +0 -78
- package/dist/ui/codeBlock.js +0 -14
- package/dist/ui/footer.js +0 -20
- package/dist/ui/hooks.js +0 -634
- package/dist/ui/ide/AgnosticSeedCard.d.ts +0 -19
- package/dist/ui/ide/AgnosticSeedCard.js +0 -48
- package/dist/ui/ide/DeckSprite.js +0 -2
- package/dist/ui/ide/JamlBuilder.d.ts +0 -1
- package/dist/ui/ide/JamlBuilder.js +0 -112
- package/dist/ui/ide/JamlEditor.js +0 -486
- package/dist/ui/ide/JamlEditorMonaco.d.ts +0 -8
- package/dist/ui/ide/JamlEditorMonaco.js +0 -78
- package/dist/ui/ide/WasmStatus.d.ts +0 -1
- package/dist/ui/ide/WasmStatus.js +0 -42
- package/dist/ui/jimboApp.js +0 -15
- package/dist/ui/jimboBackground.js +0 -27
- package/dist/ui/jimboCopyRow.js +0 -18
- package/dist/ui/jimboFilterBar.js +0 -16
- package/dist/ui/jimboFlankNav.js +0 -18
- package/dist/ui/jimboInfoCard.js +0 -26
- package/dist/ui/jimboInset.js +0 -9
- package/dist/ui/jimboSectionHeader.js +0 -9
- package/dist/ui/jimboStatGrid.js +0 -9
- package/dist/ui/jimboTabs.js +0 -22
- package/dist/ui/jimboText.js +0 -33
- package/dist/ui/jimboTooltip.js +0 -39
- package/dist/ui/jimboWordmark.js +0 -9
- package/dist/ui/mascot/JammySpeechBox.js +0 -30
- package/dist/ui/mascot/SeedMascot.js +0 -17
- package/dist/ui/mascot/index.js +0 -3
- package/dist/ui/mascot/menuConfig.js +0 -12
- package/dist/ui/panel.js +0 -24
- package/dist/ui/radial/RadialBadge.js +0 -43
- package/dist/ui/radial/RadialBreadcrumb.js +0 -18
- package/dist/ui/radial/RadialButton.js +0 -102
- package/dist/ui/radial/RadialMenu.js +0 -168
- package/dist/ui/radial/RadialPill.js +0 -15
- package/dist/ui/radial/index.js +0 -18
- package/dist/ui/radial/radialMenuStore.js +0 -122
- package/dist/ui/radial/radialMenuViewport.js +0 -59
- package/dist/ui/radial/useRadialMenu.js +0 -107
- package/dist/ui/showcase.js +0 -20
- package/dist/ui/sprites.js +0 -77
- package/dist/ui/tokens.js +0 -64
- package/dist/utils/gameCardUtils.js +0 -15
- package/dist/utils/jamlMapPreview.js +0 -106
- package/dist/utils/jamlVisualFilter.js +0 -210
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useBalatroBackground } from './hooks.js';
|
|
3
|
-
import { JimboBalatroFooter } from './footer.js';
|
|
4
|
-
/**
|
|
5
|
-
* Fullscreen WebGL CRT/spin background — the authentic Balatro hypnotic
|
|
6
|
-
* swirl, pixelated and animated. Also renders the attribution footer at the
|
|
7
|
-
* bottom of the viewport (position: fixed) so it is always present and no
|
|
8
|
-
* consumer can accidentally omit it.
|
|
9
|
-
*
|
|
10
|
-
* Drop it once at the root of your page:
|
|
11
|
-
*
|
|
12
|
-
* <JimboBackground />
|
|
13
|
-
* <YourAppContent />
|
|
14
|
-
*
|
|
15
|
-
* Resizes automatically. Disposes the animation frame + shader on unmount.
|
|
16
|
-
*/
|
|
17
|
-
export function JimboBackground() {
|
|
18
|
-
const canvasRef = useBalatroBackground();
|
|
19
|
-
return (_jsxs(_Fragment, { children: [_jsx("canvas", { ref: canvasRef, "aria-hidden": true, style: {
|
|
20
|
-
position: 'fixed',
|
|
21
|
-
inset: 0,
|
|
22
|
-
width: '100%',
|
|
23
|
-
height: '100%',
|
|
24
|
-
zIndex: -10,
|
|
25
|
-
pointerEvents: 'none',
|
|
26
|
-
} }), _jsx(JimboBalatroFooter, {})] }));
|
|
27
|
-
}
|
package/dist/ui/jimboCopyRow.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useState } from 'react';
|
|
4
|
-
import { JimboText } from './jimboText.js';
|
|
5
|
-
/**
|
|
6
|
-
* Inline copy-to-clipboard row with label + value + button.
|
|
7
|
-
* All styling via jimbo.css `.j-copy-row` classes.
|
|
8
|
-
*/
|
|
9
|
-
export function JimboCopyRow({ value, label }) {
|
|
10
|
-
const [copied, setCopied] = useState(false);
|
|
11
|
-
function copy() {
|
|
12
|
-
navigator.clipboard.writeText(value).then(() => {
|
|
13
|
-
setCopied(true);
|
|
14
|
-
setTimeout(() => setCopied(false), 1500);
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
return (_jsxs("div", { className: "j-copy-row", children: [label && (_jsx(JimboText, { size: "xs", tone: "grey", className: "j-copy-row__label", children: label })), _jsxs("div", { className: "j-copy-row__field", children: [_jsx("div", { className: "j-copy-row__value", children: _jsx(JimboText, { size: "sm", children: value }) }), _jsx("button", { type: "button", className: "j-copy-row__btn", "data-copied": copied, onClick: copy, children: copied ? 'Copied' : 'Copy' })] })] }));
|
|
18
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { JimboText } from './jimboText.js';
|
|
4
|
-
/**
|
|
5
|
-
* Generic Balatro-styled filter row: search input with floating pill label
|
|
6
|
-
* + optional sort dropdown with floating pill label.
|
|
7
|
-
*/
|
|
8
|
-
export function JimboFilterBar({ search, onSearchChange, searchPlaceholder = 'Search...', searchLabel = 'Search', sort, onSortChange, sortLabel = 'Sort By', sortOptions, className = '', style, }) {
|
|
9
|
-
return (_jsxs("div", { className: `j-filter-bar ${className}`, style: style, children: [onSearchChange ? (_jsxs("div", { className: "j-filter-bar__field", children: [_jsx("div", { className: "j-filter-bar__pill", children: _jsx(JimboText, { size: "xs", children: searchLabel }) }), _jsxs("div", { className: "j-relative", children: [_jsx("div", { className: "j-filter-bar__search-icon", children: _jsx(SearchIcon, {}) }), _jsx("input", { type: "text", value: search ?? '', onChange: (e) => onSearchChange(e.target.value), placeholder: searchPlaceholder, className: "j-filter-bar__input" })] })] })) : null, sortOptions && onSortChange ? (_jsxs("div", { className: "j-filter-bar__field", children: [_jsx("div", { className: "j-filter-bar__pill", children: _jsx(JimboText, { size: "xs", children: sortLabel }) }), _jsxs("div", { className: "j-relative", children: [_jsx("select", { value: sort ?? sortOptions[0]?.value, onChange: (e) => onSortChange(e.target.value), className: "j-filter-bar__select", children: sortOptions.map((opt) => (_jsx("option", { value: opt.value, children: opt.label }, opt.value))) }), _jsx("div", { className: "j-filter-bar__sort-icon", children: _jsx(SortIcon, {}) })] })] })) : null] }));
|
|
10
|
-
}
|
|
11
|
-
function SearchIcon() {
|
|
12
|
-
return (_jsxs("svg", { width: 24, height: 24, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 3, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [_jsx("circle", { cx: 11, cy: 11, r: 8 }), _jsx("line", { x1: 21, y1: 21, x2: 16.65, y2: 16.65 })] }));
|
|
13
|
-
}
|
|
14
|
-
function SortIcon() {
|
|
15
|
-
return (_jsxs("svg", { width: 20, height: 20, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.5, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [_jsx("polyline", { points: "7 4 7 20" }), _jsx("polyline", { points: "3 8 7 4 11 8" }), _jsx("polyline", { points: "17 20 17 4" }), _jsx("polyline", { points: "21 16 17 20 13 16" })] }));
|
|
16
|
-
}
|
package/dist/ui/jimboFlankNav.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import React from 'react';
|
|
4
|
-
/**
|
|
5
|
-
* Prev/next navigation with flanking buttons around a central stage.
|
|
6
|
-
* No hardcoded labels, no lucide dep (inline chevron SVGs).
|
|
7
|
-
*/
|
|
8
|
-
export function JimboFlankNav({ onPrev, onNext, canPrev = true, canNext = true, prevLabel = 'Previous', nextLabel = 'Next', children, className = '', style, }) {
|
|
9
|
-
return (_jsxs("div", { className: `j-flank ${className}`, style: style, children: [_jsx(NavButton, { direction: "left", onClick: onPrev, disabled: !canPrev, "aria-label": prevLabel }), _jsx("div", { className: "j-flank__content", children: children }), _jsx(NavButton, { direction: "right", onClick: onNext, disabled: !canNext, "aria-label": nextLabel })] }));
|
|
10
|
-
}
|
|
11
|
-
function NavButton({ direction, onClick, disabled, 'aria-label': ariaLabel, }) {
|
|
12
|
-
const [pressed, setPressed] = React.useState(false);
|
|
13
|
-
return (_jsx("button", { type: "button", className: "j-flank__btn", "data-pressed": pressed && !disabled, onClick: onClick, disabled: disabled, "aria-label": ariaLabel, title: ariaLabel, onMouseDown: () => !disabled && setPressed(true), onMouseUp: () => setPressed(false), onMouseLeave: () => setPressed(false), onTouchStart: () => !disabled && setPressed(true), onTouchEnd: () => setPressed(false), children: _jsx(ChevronSvg, { direction: direction }) }));
|
|
14
|
-
}
|
|
15
|
-
function ChevronSvg({ direction }) {
|
|
16
|
-
const points = direction === 'left' ? '18,4 8,14 18,24' : '10,4 20,14 10,24';
|
|
17
|
-
return (_jsx("svg", { width: 28, height: 28, viewBox: "0 0 28 28", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: _jsx("polyline", { points: points }) }));
|
|
18
|
-
}
|
package/dist/ui/jimboInfoCard.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
/**
|
|
4
|
-
* Generic clickable row card — used for filter lists, seed lists, etc.
|
|
5
|
-
* Border color set via tone. All styling via jimbo.css `.j-info-card`.
|
|
6
|
-
*/
|
|
7
|
-
export function JimboInfoCard({ tone, children, className = '', ...props }) {
|
|
8
|
-
const borderClass = tone ? `j-border--${tone}` : '';
|
|
9
|
-
return (_jsx("div", { className: `j-info-card ${borderClass} ${className}`, style: tone ? { borderColor: undefined } : undefined, ...props, children: children }));
|
|
10
|
-
}
|
|
11
|
-
/** Main body area inside an InfoCard (flex: 1, overflow-safe). */
|
|
12
|
-
export function JimboInfoCardBody({ children, className = '' }) {
|
|
13
|
-
return _jsx("div", { className: `j-info-card__body ${className}`, children: children });
|
|
14
|
-
}
|
|
15
|
-
/** Title line inside an InfoCard body. */
|
|
16
|
-
export function JimboInfoCardTitle({ children, className = '' }) {
|
|
17
|
-
return _jsx("div", { className: `j-info-card__title ${className}`, children: children });
|
|
18
|
-
}
|
|
19
|
-
/** Subtitle line inside an InfoCard body. */
|
|
20
|
-
export function JimboInfoCardSub({ children, className = '' }) {
|
|
21
|
-
return _jsx("div", { className: `j-info-card__sub ${className}`, children: children });
|
|
22
|
-
}
|
|
23
|
-
/** Right-side aside area inside an InfoCard. */
|
|
24
|
-
export function JimboInfoCardAside({ children, className = '' }) {
|
|
25
|
-
return _jsx("div", { className: `j-info-card__aside ${className}`, children: children });
|
|
26
|
-
}
|
package/dist/ui/jimboInset.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
/**
|
|
4
|
-
* Dark recessed content area — for log output, recent finds, etc.
|
|
5
|
-
* All styling via jimbo.css `.j-inset` class.
|
|
6
|
-
*/
|
|
7
|
-
export function JimboInset({ children, className = '', ...props }) {
|
|
8
|
-
return (_jsx("div", { className: `j-inset ${className}`, ...props, children: children }));
|
|
9
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
/**
|
|
4
|
-
* Colored tag + horizontal rule — reusable section divider.
|
|
5
|
-
* All styling via jimbo.css `.j-section-header` classes + tone utilities.
|
|
6
|
-
*/
|
|
7
|
-
export function JimboSectionHeader({ label, tone = 'blue', className = '' }) {
|
|
8
|
-
return (_jsxs("div", { className: `j-section-header ${className}`, children: [_jsx("div", { className: `j-section-header__tag j-bg--${tone}`, children: label }), _jsx("div", { className: `j-section-header__rule j-bg--${tone}` })] }));
|
|
9
|
-
}
|
package/dist/ui/jimboStatGrid.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
/**
|
|
4
|
-
* 3-column stat bar — value on top, label below.
|
|
5
|
-
* All styling via jimbo.css `.j-stat-grid` classes.
|
|
6
|
-
*/
|
|
7
|
-
export function JimboStatGrid({ items, className = '', ...props }) {
|
|
8
|
-
return (_jsx("div", { className: `j-stat-grid ${className}`, ...props, children: items.map((item) => (_jsxs("div", { children: [_jsx("div", { className: "j-stat-grid__value", children: item.value }), _jsx("div", { className: "j-stat-grid__label", children: item.label })] }, item.label))) }));
|
|
9
|
-
}
|
package/dist/ui/jimboTabs.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { JimboText } from './jimboText.js';
|
|
4
|
-
/**
|
|
5
|
-
* Horizontal tab navigation with bouncing triangle indicator on the active
|
|
6
|
-
* tab. Triangle attaches to each button and animates only on the active one.
|
|
7
|
-
*/
|
|
8
|
-
export function JimboTabs({ tabs, activeTab, onTabChange, className = '', style }) {
|
|
9
|
-
return (_jsx("div", { className: `j-tabs ${className}`, style: style, children: tabs.map((tab) => (_jsx(TabButton, { label: tab.label, active: activeTab === tab.id, onClick: () => onTabChange(tab.id) }, tab.id))) }));
|
|
10
|
-
}
|
|
11
|
-
function TabButton({ label, active, onClick }) {
|
|
12
|
-
return (_jsxs("div", { className: "j-tab", "data-active": active, children: [_jsx("div", { className: "j-tab__indicator", "data-active": active, "aria-hidden": true, children: _jsx("svg", { width: 14, height: 10, viewBox: "0 0 14 10", children: _jsx("polygon", { points: "7,10 0,0 14,0" }) }) }), _jsx("button", { type: "button", className: "j-tab__btn", "data-active": active, onClick: onClick, children: _jsx(JimboText, { size: "sm", tone: "default", children: label }) })] }));
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Vertical tab strip — rotated labels (writing-mode) for space efficiency.
|
|
16
|
-
*/
|
|
17
|
-
export function JimboVerticalTabs({ tabs, activeTab, onTabChange, className = '', style }) {
|
|
18
|
-
return (_jsx("div", { className: `j-vtabs ${className}`, style: style, children: tabs.map((tab) => {
|
|
19
|
-
const isActive = activeTab === tab.id;
|
|
20
|
-
return (_jsx("button", { type: "button", className: "j-vtab", "data-active": isActive, onClick: () => onTabChange(tab.id), children: _jsx(JimboText, { size: "sm", tone: isActive ? 'default' : 'grey', children: tab.label }) }, tab.id));
|
|
21
|
-
}) }));
|
|
22
|
-
}
|
package/dist/ui/jimboText.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
/**
|
|
4
|
-
* Canonical pixel-font text wrapper. Uses `m6x11plus` as its family and
|
|
5
|
-
* applies the authentic Balatro drop shadow by default. Prefer this over
|
|
6
|
-
* hand-rolling `fontFamily: 'm6x11plus, monospace'` + `textShadow` strings
|
|
7
|
-
* throughout consumers — it keeps the styling drift-free.
|
|
8
|
-
*
|
|
9
|
-
* Requires `import 'jaml-ui/fonts.css'` somewhere in the consumer bundle
|
|
10
|
-
* so the @font-face declaration lands (font is base64-embedded, no
|
|
11
|
-
* runtime fetch).
|
|
12
|
-
*/
|
|
13
|
-
export function JimboText({ tone = 'default', size = 'md', shadow = true, uppercase = false, dance = false, letterSpacing, as: Tag = 'span', className = '', style, children, ...rest }) {
|
|
14
|
-
const sizeClass = `j-text--${size}`;
|
|
15
|
-
const toneClass = `j-text--${tone}`;
|
|
16
|
-
const shadowClass = shadow ? '' : 'j-text--no-shadow';
|
|
17
|
-
const upperClass = uppercase ? 'j-text--upper' : '';
|
|
18
|
-
const danceClass = dance ? 'j-text--dance-container' : '';
|
|
19
|
-
const inlineStyle = {};
|
|
20
|
-
if (letterSpacing != null) {
|
|
21
|
-
inlineStyle.letterSpacing = letterSpacing;
|
|
22
|
-
}
|
|
23
|
-
else if (uppercase && letterSpacing == null) {
|
|
24
|
-
inlineStyle.letterSpacing = 2;
|
|
25
|
-
}
|
|
26
|
-
if (style)
|
|
27
|
-
Object.assign(inlineStyle, style);
|
|
28
|
-
let content = children;
|
|
29
|
-
if (dance && typeof children === 'string') {
|
|
30
|
-
content = children.split('').map((char, i) => (_jsx("span", { className: "j-font-dance-char", style: { animationDelay: `${i * -0.15}s` }, children: char === ' ' ? '\u00A0' : char }, i)));
|
|
31
|
-
}
|
|
32
|
-
return (_jsx(Tag, { className: `j-text ${sizeClass} ${toneClass} ${shadowClass} ${upperClass} ${danceClass} ${className}`.trim(), style: Object.keys(inlineStyle).length > 0 ? inlineStyle : undefined, ...rest, children: content }));
|
|
33
|
-
}
|
package/dist/ui/jimboTooltip.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import React, { useCallback } from 'react';
|
|
3
|
-
import { useJimboTooltip } from './hooks.js';
|
|
4
|
-
function assignRef(ref, value) {
|
|
5
|
-
if (typeof ref === 'function')
|
|
6
|
-
ref(value);
|
|
7
|
-
else if (ref && typeof ref === 'object') {
|
|
8
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
-
ref.current = value;
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Canonical Balatro-style tooltip: dark panel, silver border, pixel font.
|
|
14
|
-
* Wrap any target to get a hover/focus popover.
|
|
15
|
-
*/
|
|
16
|
-
export function JimboTooltip({ content, children, mode = 'snap', placement = 'auto', delay = 80, maxWidth = 280, disabled = false, }) {
|
|
17
|
-
const { visible, pos, targetRef, tooltipRef, show, hide, handleMouseMove, } = useJimboTooltip({ mode, placement, delay, disabled });
|
|
18
|
-
const child = React.Children.only(children);
|
|
19
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
|
-
const childRef = child.ref;
|
|
21
|
-
const refHandler = useCallback((node) => {
|
|
22
|
-
targetRef.current = node;
|
|
23
|
-
assignRef(childRef, node);
|
|
24
|
-
}, [childRef, targetRef]);
|
|
25
|
-
const wrapped = React.cloneElement(child, {
|
|
26
|
-
ref: refHandler,
|
|
27
|
-
onMouseEnter: (e) => { show(); child.props.onMouseEnter?.(e); },
|
|
28
|
-
onMouseLeave: (e) => { hide(); child.props.onMouseLeave?.(e); },
|
|
29
|
-
onFocus: (e) => { show(); child.props.onFocus?.(e); },
|
|
30
|
-
onBlur: (e) => { hide(); child.props.onBlur?.(e); },
|
|
31
|
-
onMouseMove: (e) => { handleMouseMove(e); child.props.onMouseMove?.(e); },
|
|
32
|
-
});
|
|
33
|
-
return (_jsxs(_Fragment, { children: [wrapped, visible ? (_jsx("div", { ref: tooltipRef, role: "tooltip", className: "j-tooltip", style: {
|
|
34
|
-
left: pos?.left ?? -9999,
|
|
35
|
-
top: pos?.top ?? -9999,
|
|
36
|
-
maxWidth,
|
|
37
|
-
opacity: pos ? 1 : 0,
|
|
38
|
-
}, children: content })) : null] }));
|
|
39
|
-
}
|
package/dist/ui/jimboWordmark.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
/**
|
|
4
|
-
* Title + subtitle hero block. Gold title, grey subtitle.
|
|
5
|
-
* All styling via jimbo.css `.j-wordmark` classes.
|
|
6
|
-
*/
|
|
7
|
-
export function JimboWordmark({ title, subtitle, className = '' }) {
|
|
8
|
-
return (_jsxs("div", { className: `j-wordmark ${className}`, children: [_jsx("div", { className: "j-wordmark__title", children: title }), subtitle && _jsx("div", { className: "j-wordmark__sub", children: subtitle })] }));
|
|
9
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { splitTtsDisplay } from '../../lib/tts/splitTtsDisplay';
|
|
4
|
-
/** Fixed chrome so the home announcement always occupies one predictable size (ai-elements, same family as chat). */
|
|
5
|
-
const speechBoxFrame = 'w-[20.5rem] max-w-[calc(100vw-2.25rem)] min-h-[7.25rem] h-[7.25rem] rounded-xl border border-white/15 bg-black/72 px-4 py-3 text-center shadow-lg backdrop-blur-md';
|
|
6
|
-
const speechText = 'whitespace-pre-wrap break-words text-sm font-normal leading-relaxed tracking-normal text-[#f6f0d5] antialiased';
|
|
7
|
-
// Simple utility to concatenate classes instead of importing tailwind-merge (for agnostic component)
|
|
8
|
-
function cn(...classes) {
|
|
9
|
-
return classes.filter(Boolean).join(' ');
|
|
10
|
-
}
|
|
11
|
-
export function JammySpeechBox({ text, highlightPos, activeSentenceRange, className, }) {
|
|
12
|
-
const raw = (text ?? '').trim();
|
|
13
|
-
if (!raw)
|
|
14
|
-
return null;
|
|
15
|
-
const split = splitTtsDisplay(raw, highlightPos, activeSentenceRange, { stripMarkdown: true });
|
|
16
|
-
const ttsOff = highlightPos == null;
|
|
17
|
-
const displaySource = split
|
|
18
|
-
? `${split.prefix}${split.spoken}${split.pending}${split.suffix}`
|
|
19
|
-
: raw.replace(/```[\s\S]*?```/g, '').replace(/\*\*/g, '').trim();
|
|
20
|
-
if (!displaySource)
|
|
21
|
-
return null;
|
|
22
|
-
const prefix = ttsOff || !split ? '' : split.prefix;
|
|
23
|
-
const spoken = !split || ttsOff ? displaySource : split.spoken;
|
|
24
|
-
const pending = !split || ttsOff ? '' : split.pending;
|
|
25
|
-
const suffix = !split || ttsOff ? '' : split.suffix;
|
|
26
|
-
return (_jsx("div", { "data-testid": "jammy-announcement", className: cn(
|
|
27
|
-
// Anchor to the scene center so Jammy stays centered inside the orbital menu,
|
|
28
|
-
// with the announcement floating just above the mascot's head.
|
|
29
|
-
'pointer-events-none absolute top-1/2 left-1/2 z-20 flex w-full max-w-[calc(100vw-2.25rem)] -translate-x-1/2 -translate-y-[calc(100%+5.75rem)] justify-center sm:-translate-y-[calc(100%+6.25rem)]', className), children: _jsx("div", { className: "max-w-none", children: _jsx("div", { className: cn(speechBoxFrame, 'flex flex-col items-center justify-center overflow-hidden text-[#f6f0d5]!'), children: _jsxs("p", { className: cn(speechText, 'm-0 w-full max-w-full'), children: [_jsx("span", { className: "text-[#f6f0d5]", children: prefix }), _jsx("span", { className: "text-[#f6f0d5]", children: spoken }), _jsx("span", { className: "text-[#f6f0d5]/35", children: pending }), _jsx("span", { className: "text-[#f6f0d5]/35", children: suffix })] }) }) }) }));
|
|
30
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import { RadialMenu } from "../radial";
|
|
4
|
-
export const SeedMascot = React.memo(function SeedMascot({ size = 160, mascotTranslateY = 0, welcomeEntranceLift = 0, mascotMotionClass = "jammy-jimbo-idle", onTap, showRadialMenu = false, showClosingRadialMenu = false, radialItems = [], currentMenu = "main", onItemClick, onBack, showPageControls = false, onPagePrev, onPageNext, breadcrumb, baseOrbitRadius = 66, }) {
|
|
5
|
-
// Orbit geometry — tight ring around Jammy; small per-item nudge only when many slots.
|
|
6
|
-
const orbitalCount = radialItems.filter((it) => !("_south" in it && it._south)).length;
|
|
7
|
-
const mascotHalf = size / 2;
|
|
8
|
-
const minOrbitR = mascotHalf + 42;
|
|
9
|
-
const orbitRadiusX = Math.max(84, baseOrbitRadius + orbitalCount * 3, minOrbitR);
|
|
10
|
-
const orbitRadiusY = orbitRadiusX;
|
|
11
|
-
return (_jsxs("div", { className: "relative flex w-full flex-col items-center justify-center", children: [radialItems.length > 0 && (showRadialMenu || showClosingRadialMenu) ? (_jsx(RadialMenu, { items: radialItems, showClosing: showClosingRadialMenu, mascotSizePx: size, orbitRadiusX: orbitRadiusX, orbitRadiusY: orbitRadiusY, mascotTranslateY: mascotTranslateY, currentMenu: currentMenu, onItemClick: onItemClick || (() => { }), onBack: onBack || (() => { }), showPageControls: showPageControls, onPagePrev: onPagePrev, onPageNext: onPageNext, breadcrumb: breadcrumb })) : null, _jsx("div", { className: "relative z-20 transition-transform duration-500 ease-[cubic-bezier(0.22,0.92,0.2,1.08)]", style: {
|
|
12
|
-
transform: `translateY(${mascotTranslateY + welcomeEntranceLift}px)`,
|
|
13
|
-
}, children: _jsx("button", { type: "button", onClick: onTap, className: "relative block cursor-pointer rounded-full filter-[drop-shadow(0_4_12_rgba(0,0,0,0.5))] transition-transform duration-300 ease-[cubic-bezier(0.22,0.9,0.3,1.12)] will-change-transform [-webkit-backface-visibility:hidden] backface-hidden hover:scale-105 focus-visible:ring-4 focus-visible:ring-orange-500 active:scale-95", style: {
|
|
14
|
-
width: size,
|
|
15
|
-
height: size,
|
|
16
|
-
}, "aria-label": "Tap Jammy to open chat or the menu", children: _jsx("span", { className: `pointer-events-none absolute inset-0 block ${mascotMotionClass}`, style: { transformOrigin: "50% 80%" }, children: _jsx("img", { src: "/jaml-logo.png", alt: "Jammy", className: "absolute inset-0 block h-full w-full object-contain" }) }) }) })] }));
|
|
17
|
-
});
|
package/dist/ui/mascot/index.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
// ── Strict Color Semantics ────────────────────────────────────────────────────
|
|
2
|
-
// RED = Default button, opens submenu/panel/tool/modal
|
|
3
|
-
// BLUE = CHAT — sends a message to Jammy specifically
|
|
4
|
-
// ORANGE = TOGGLE on/off state, also used for UPLOAD
|
|
5
|
-
export const MenuColors = {
|
|
6
|
-
SUBMENU: "red", // Opens submenu/panel/tool/modal
|
|
7
|
-
CHAT: "blue", // Sends chat message to Jammy
|
|
8
|
-
TOGGLE: "orange", // On/off switch
|
|
9
|
-
ACTION: "red", // Immediate UI action without chat message
|
|
10
|
-
START: "green", // Special color for START button on welcome screen
|
|
11
|
-
UPLOAD: "orange", // File upload action - uses Jimbo orange
|
|
12
|
-
};
|
package/dist/ui/panel.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { memo } from 'react';
|
|
4
|
-
import { useSway } from './hooks.js';
|
|
5
|
-
import { JimboText } from './jimboText.js';
|
|
6
|
-
export const JimboPanel = memo(({ children, className = '', sway = false, onBack, hideBack = false, style, ...props }) => {
|
|
7
|
-
const panelRef = useSway(sway);
|
|
8
|
-
return (_jsxs("div", { ref: panelRef, className: `j-panel ${className}`, style: style, ...props, children: [_jsx("div", { className: "j-panel__body", children: children }), onBack && !hideBack && (_jsx("div", { className: "j-panel__back", children: _jsx(JimboBackButton, { onClick: onBack }) }))] }));
|
|
9
|
-
});
|
|
10
|
-
JimboPanel.displayName = 'JimboPanel';
|
|
11
|
-
export const JimboInnerPanel = memo(({ children, className = '', style, ...props }) => (_jsx("div", { className: `j-inner-panel ${className}`, style: style, ...props, children: children })));
|
|
12
|
-
JimboInnerPanel.displayName = 'JimboInnerPanel';
|
|
13
|
-
export function JimboButton({ tone = 'orange', size = 'md', fullWidth = false, disabled = false, uppercase = false, onClick, style, className = '', children, }) {
|
|
14
|
-
const textSize = size === 'xs' ? 'xs' : size === 'sm' ? 'sm' : size === 'lg' ? 'lg' : 'md';
|
|
15
|
-
return (_jsx("button", { type: "button", className: `j-btn j-btn--${tone} j-btn--${size} ${fullWidth ? 'j-btn--full' : ''} ${disabled ? 'j-btn--disabled' : ''} ${className}`, disabled: disabled, onClick: onClick, style: style, children: _jsx("div", { className: "j-btn__face", children: _jsx(JimboText, { size: textSize, uppercase: uppercase, children: children }) }) }));
|
|
16
|
-
}
|
|
17
|
-
export function JimboBackButton({ onClick }) {
|
|
18
|
-
return (_jsx("div", { className: "j-flex j-justify-center j-w-full", style: { padding: '4px 0' }, children: _jsx(JimboButton, { tone: "orange", size: "md", fullWidth: true, onClick: onClick, className: "j-back-btn", children: "Back" }) }));
|
|
19
|
-
}
|
|
20
|
-
export function JimboModal({ children, open, onClose, title, className, showBack = true }) {
|
|
21
|
-
if (!open)
|
|
22
|
-
return null;
|
|
23
|
-
return (_jsx("div", { className: "j-modal-overlay", children: _jsxs(JimboPanel, { onBack: showBack ? onClose : undefined, className: `j-modal ${className ?? ''}`, children: [title && _jsx(JimboText, { as: "h2", size: "lg", className: "j-modal__title", children: title }), children] }) }));
|
|
24
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import clsx from "clsx";
|
|
4
|
-
import { twMerge } from "tailwind-merge";
|
|
5
|
-
import { JimboColorOption } from "../tokens";
|
|
6
|
-
import "./radial-navigation.css";
|
|
7
|
-
import { BUTTON_THEMES } from "./RadialButton";
|
|
8
|
-
const INDICATOR_STYLES = {
|
|
9
|
-
success: { bg: JimboColorOption.GREEN_TEXT, border: JimboColorOption.BORDER_SILVER },
|
|
10
|
-
error: { bg: JimboColorOption.DARK_RED, border: JimboColorOption.DARK_GREY },
|
|
11
|
-
loading: { bg: JimboColorOption.GREY, border: JimboColorOption.DARK_GREY },
|
|
12
|
-
info: { bg: JimboColorOption.BLUE, border: JimboColorOption.DARK_GREY },
|
|
13
|
-
warning: { bg: JimboColorOption.ORANGE, border: JimboColorOption.DARK_GREY },
|
|
14
|
-
};
|
|
15
|
-
/**
|
|
16
|
-
* Display-only radial status indicator.
|
|
17
|
-
*
|
|
18
|
-
* Visually matches RadialButton but rendered as a `<div>` with no click handler.
|
|
19
|
-
* Shows a status dot (green/red/grey) + label text.
|
|
20
|
-
*/
|
|
21
|
-
export function RadialBadge({ label, state, color = "red", tooltip, className }) {
|
|
22
|
-
const theme = BUTTON_THEMES[color];
|
|
23
|
-
const altText = tooltip ?? `badge: ${label}`;
|
|
24
|
-
return (_jsxs("div", { role: "status", "aria-label": altText, title: altText, className: twMerge(clsx("flex min-w-[60px] items-center justify-center gap-1.5 rounded-[11px] px-[10px] py-[2px] select-none sm:min-w-[64px] sm:px-[14px]", "text-[11.5px] font-normal", "shadow-[var(--btn-shadow)]", className)), style: {
|
|
25
|
-
backgroundColor: theme.bg,
|
|
26
|
-
border: "none",
|
|
27
|
-
height: 24,
|
|
28
|
-
"--btn-shadow": `0 4px 0 0 ${theme.shadow}`,
|
|
29
|
-
}, children: [_jsx("div", { className: twMerge("h-[9px] w-[9px] shrink-0 rounded-full border", (state === "error" || state === "loading") && "animate-pulse"), style: {
|
|
30
|
-
backgroundColor: INDICATOR_STYLES[state].bg,
|
|
31
|
-
borderWidth: 1,
|
|
32
|
-
borderColor: INDICATOR_STYLES[state].border,
|
|
33
|
-
boxShadow: state === "success"
|
|
34
|
-
? "0 0 8px rgba(53,189,134,0.5)"
|
|
35
|
-
: state === "error"
|
|
36
|
-
? "0 0 8px rgba(160,39,33,0.5)"
|
|
37
|
-
: state === "info"
|
|
38
|
-
? "0 0 8px rgba(62,176,248,0.5)"
|
|
39
|
-
: state === "warning"
|
|
40
|
-
? "0 0 8px rgba(254,166,42,0.5)"
|
|
41
|
-
: "none",
|
|
42
|
-
} }), _jsx("span", { className: "jimbo-radial-label jimbo-radial-label--badge", children: label })] }));
|
|
43
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { twMerge } from "tailwind-merge";
|
|
4
|
-
const BREADCRUMB_STYLE = {
|
|
5
|
-
backgroundColor: "#1a1e2e",
|
|
6
|
-
border: "1.5px solid rgba(255,255,255,0.18)",
|
|
7
|
-
color: "#f6f0d5",
|
|
8
|
-
opacity: 0.92,
|
|
9
|
-
};
|
|
10
|
-
/**
|
|
11
|
-
* Breadcrumb nav pill — "currently viewing" indicator.
|
|
12
|
-
*
|
|
13
|
-
* Sits above the Back button to show the user's position in the menu tree.
|
|
14
|
-
* Non-interactive, dark styling, same pill family as orbital buttons.
|
|
15
|
-
*/
|
|
16
|
-
export function RadialBreadcrumb({ label, title, className }) {
|
|
17
|
-
return (_jsxs("div", { role: "status", "aria-label": title ?? `In: ${label}`, title: title ?? `In: ${label}`, className: twMerge("pointer-events-auto flex items-center gap-1 rounded-[11px] px-[10px] py-[2px] font-serif text-[11.5px] font-normal shadow-[0_4px_0_0_rgba(30,30,30,0.9)] select-none sm:px-[14px]", className), style: BREADCRUMB_STYLE, children: [_jsx("span", { className: "text-[9.5px] opacity-50", children: "\u203A" }), _jsx("span", { className: "whitespace-nowrap", children: label })] }));
|
|
18
|
-
}
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useState } from "react";
|
|
4
|
-
import clsx from "clsx";
|
|
5
|
-
import { twMerge } from "tailwind-merge";
|
|
6
|
-
import { JimboColorOption } from "../tokens";
|
|
7
|
-
import "./radial-navigation.css";
|
|
8
|
-
const BUTTON_THEMES = {
|
|
9
|
-
orange: { bg: JimboColorOption.ORANGE, shadow: JimboColorOption.DARK_ORANGE, text: JimboColorOption.WHITE },
|
|
10
|
-
purple: { bg: JimboColorOption.PURPLE, shadow: JimboColorOption.DARK_PURPLE, text: JimboColorOption.WHITE },
|
|
11
|
-
red: { bg: JimboColorOption.RED, shadow: JimboColorOption.DARK_RED, text: JimboColorOption.WHITE },
|
|
12
|
-
green: { bg: JimboColorOption.GREEN, shadow: JimboColorOption.DARK_GREEN, text: JimboColorOption.WHITE },
|
|
13
|
-
blue: { bg: JimboColorOption.BLUE, shadow: JimboColorOption.DARK_BLUE, text: JimboColorOption.WHITE },
|
|
14
|
-
"seed-zero": { bg: JimboColorOption.BLACK, shadow: "#111111", text: JimboColorOption.WHITE },
|
|
15
|
-
"seed-low": { bg: JimboColorOption.DARK_GREY, shadow: JimboColorOption.DARKEST, text: JimboColorOption.WHITE },
|
|
16
|
-
"seed-top": { bg: JimboColorOption.DARKEST, shadow: JimboColorOption.BLACK, text: JimboColorOption.GOLD },
|
|
17
|
-
};
|
|
18
|
-
// ── Shared base classes ───────────────────────────────────────────────────────
|
|
19
|
-
const BUTTON_SHADOW = "0 4px 0 0 rgba(0,0,0,0.8)";
|
|
20
|
-
const BASE_CLASSES = clsx("group flex items-center justify-center gap-1.5 rounded-[10px] border-none px-[10px] py-[3px] outline-none select-none", "font-normal", "transition-[transform,box-shadow] duration-[80ms] ease-out");
|
|
21
|
-
const INTERACTIVE_CLASSES = "cursor-pointer";
|
|
22
|
-
const DISABLED_CLASSES = "cursor-not-allowed opacity-67";
|
|
23
|
-
const WIDE_CLASSES = "w-[130px] sm:w-[160px]";
|
|
24
|
-
const NORMAL_WIDTH = "min-w-[54px] sm:min-w-[64px]";
|
|
25
|
-
/**
|
|
26
|
-
* Polymorphic radial navigation button.
|
|
27
|
-
*
|
|
28
|
-
* Replaces four separate components (Button, CountIndicator, Toggle, Back/Start)
|
|
29
|
-
* with a single component using a `variant` prop.
|
|
30
|
-
*
|
|
31
|
-
* All variants share the Balatro-styled pill: 3D bottom-edge shadow, press-down on active.
|
|
32
|
-
*/
|
|
33
|
-
export function RadialButton(props) {
|
|
34
|
-
const { label, tooltip, onClick, className } = props;
|
|
35
|
-
const variant = props.variant ?? "action";
|
|
36
|
-
const [isPressed, setIsPressed] = useState(false);
|
|
37
|
-
// South pills (Start / Back): same Balatro orange as Back — never green-vs-red split.
|
|
38
|
-
const isSouthPill = variant === "start" || variant === "back";
|
|
39
|
-
let colorKey;
|
|
40
|
-
if (isSouthPill) {
|
|
41
|
-
colorKey = props.color ?? "orange";
|
|
42
|
-
}
|
|
43
|
-
else if (variant === "toggle") {
|
|
44
|
-
colorKey = props.color ?? "red";
|
|
45
|
-
}
|
|
46
|
-
else if (variant === "count") {
|
|
47
|
-
colorKey = props.color ?? "red";
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
colorKey = props.color ?? "red";
|
|
51
|
-
}
|
|
52
|
-
const theme = BUTTON_THEMES[colorKey];
|
|
53
|
-
const altText = _computeAltText(props, variant);
|
|
54
|
-
const isDisabled = variant === "toggle" && props.disabled === true;
|
|
55
|
-
const isWide = variant === "back" || variant === "start";
|
|
56
|
-
return (_jsxs("button", { type: "button", onClick: isDisabled ? undefined : onClick, onPointerDown: isDisabled
|
|
57
|
-
? undefined
|
|
58
|
-
: (e) => {
|
|
59
|
-
setIsPressed(true);
|
|
60
|
-
e.currentTarget.setPointerCapture(e.pointerId);
|
|
61
|
-
}, onPointerUp: isDisabled ? undefined : () => setIsPressed(false), onPointerCancel: isDisabled ? undefined : () => setIsPressed(false), onPointerLeave: isDisabled ? undefined : () => setIsPressed(false), "aria-label": altText, title: tooltip ?? altText, disabled: isDisabled, className: twMerge(clsx(BASE_CLASSES, isWide ? WIDE_CLASSES : NORMAL_WIDTH, isDisabled ? DISABLED_CLASSES : INTERACTIVE_CLASSES, className)), style: {
|
|
62
|
-
backgroundColor: theme.bg,
|
|
63
|
-
boxShadow: isPressed && !isDisabled ? "none" : BUTTON_SHADOW,
|
|
64
|
-
transform: isPressed && !isDisabled ? "translateY(4px)" : "translateY(0)",
|
|
65
|
-
...(props.style ?? {}),
|
|
66
|
-
}, children: [variant === "toggle" && _jsx(ToggleDot, { active: props.active, disabled: isDisabled }), _jsx("span", { className: "jimbo-radial-label jimbo-radial-label--action", children: label }), variant === "count" && _jsx(CountBadge, { count: props.count, icon: props.icon })] }));
|
|
67
|
-
}
|
|
68
|
-
// ── Internal sub-components ───────────────────────────────────────────────────
|
|
69
|
-
function ToggleDot({ active }) {
|
|
70
|
-
const dotStyle = active
|
|
71
|
-
? { backgroundColor: JimboColorOption.GREEN_TEXT, borderColor: JimboColorOption.BORDER_SILVER }
|
|
72
|
-
: { backgroundColor: JimboColorOption.DARK_RED, borderColor: JimboColorOption.DARK_GREY };
|
|
73
|
-
return (_jsx("div", { className: twMerge("h-[9px] w-[9px] shrink-0 rounded-full border"), style: { borderWidth: 1, ...dotStyle } }));
|
|
74
|
-
}
|
|
75
|
-
function CountBadge({ count, icon }) {
|
|
76
|
-
if (icon) {
|
|
77
|
-
return (_jsx("span", { className: "inline-flex items-center justify-center text-[10px] leading-none", style: { marginLeft: 2 }, "aria-hidden": "true", children: icon }));
|
|
78
|
-
}
|
|
79
|
-
return (_jsx("span", { className: "inline-flex items-center justify-center rounded-full font-mono leading-none", style: {
|
|
80
|
-
fontSize: "10px",
|
|
81
|
-
backgroundColor: JimboColorOption.DARKEST,
|
|
82
|
-
color: count > 0 ? JimboColorOption.GOLD : JimboColorOption.GREY,
|
|
83
|
-
minWidth: 16,
|
|
84
|
-
height: 16,
|
|
85
|
-
padding: "2px 4px",
|
|
86
|
-
marginLeft: 2,
|
|
87
|
-
}, children: count }));
|
|
88
|
-
}
|
|
89
|
-
function _computeAltText(props, variant) {
|
|
90
|
-
if (props.tooltip)
|
|
91
|
-
return props.tooltip;
|
|
92
|
-
switch (variant) {
|
|
93
|
-
case "toggle":
|
|
94
|
-
return `toggle: ${props.label} (${props.active ? "on" : "off"})`;
|
|
95
|
-
case "count":
|
|
96
|
-
return `${props.label}: ${props.icon ?? props.count}`;
|
|
97
|
-
default:
|
|
98
|
-
return `button: ${props.label}`;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
// Re-export themes for badge usage
|
|
102
|
-
export { BUTTON_THEMES };
|