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.
Files changed (233) hide show
  1. package/README.md +0 -13
  2. package/assets/WeeJokerExampleDAilyGame.png +0 -0
  3. package/assets/balatro-stake-chips.png +0 -0
  4. package/dist/assets.d.ts +1 -2
  5. package/dist/chunks/Layer-BBPJFHfs.js +17 -0
  6. package/dist/chunks/Layer-BBPJFHfs.js.map +1 -0
  7. package/dist/chunks/assets-RWUiFSTc.js +37 -0
  8. package/dist/chunks/assets-RWUiFSTc.js.map +1 -0
  9. package/dist/chunks/motelyItemDecoder-CueyZ0XD.js +6039 -0
  10. package/dist/chunks/motelyItemDecoder-CueyZ0XD.js.map +1 -0
  11. package/dist/chunks/spriteMapper-CFjN0_TV.js +2415 -0
  12. package/dist/chunks/spriteMapper-CFjN0_TV.js.map +1 -0
  13. package/dist/chunks/tokens-B65Fzble.js +57 -0
  14. package/dist/chunks/tokens-B65Fzble.js.map +1 -0
  15. package/dist/chunks/ui-5cBy3zAm.js +1387 -0
  16. package/dist/chunks/ui-5cBy3zAm.js.map +1 -0
  17. package/dist/components/AnalyzerExplorer.d.ts +1 -1
  18. package/dist/components/CardFan.d.ts +1 -1
  19. package/dist/components/CardList.d.ts +1 -1
  20. package/dist/components/DeckSprite.d.ts +1 -1
  21. package/dist/components/JamlAestheticSelector.d.ts +1 -1
  22. package/dist/components/JamlAnalyzerFullscreen.d.ts +5 -5
  23. package/dist/components/JamlCurator.d.ts +1 -6
  24. package/dist/components/JamlIde.d.ts +5 -5
  25. package/dist/components/JamlSeedInput.d.ts +1 -1
  26. package/dist/components/JamlSpeedometer.d.ts +1 -1
  27. package/dist/components/MotelyVersionBadge.d.ts +1 -1
  28. package/dist/components/Standardcard.d.ts +1 -1
  29. package/dist/components/jamlMap/CategoryPicker.d.ts +3 -3
  30. package/dist/components/jamlMap/JamlMapEditor.d.ts +1 -1
  31. package/dist/components/jamlMap/JokerPicker.d.ts +1 -1
  32. package/dist/components/jamlMap/MysterySlot.d.ts +2 -2
  33. package/dist/components/jamlMap/index.d.ts +4 -4
  34. package/dist/core.d.ts +5 -5
  35. package/dist/core.js +27 -5
  36. package/dist/core.js.map +1 -0
  37. package/dist/decode/motelyItemDecoder.d.ts +0 -10
  38. package/dist/decode/motelySprite.d.ts +1 -1
  39. package/dist/fonts/m6x11plus.otf +0 -0
  40. package/dist/hooks/analyzerStreamRegistry.d.ts +2 -2
  41. package/dist/hooks/useAnalyzer.d.ts +3 -3
  42. package/dist/hooks/useSearch.d.ts +2 -2
  43. package/dist/index.d.ts +29 -31
  44. package/dist/index.js +16721 -34
  45. package/dist/index.js.map +1 -0
  46. package/dist/lib/const.d.ts +2 -2
  47. package/dist/lib/hooks/useDragScroll.d.ts +1 -1
  48. package/dist/lib/hooks/useJamlFilter.d.ts +2 -2
  49. package/dist/lib/hooks/useSeedAnalyzer.d.ts +2 -2
  50. package/dist/lib/utils.d.ts +1 -1
  51. package/dist/motely.d.ts +4 -3
  52. package/dist/motely.js +65 -3
  53. package/dist/motely.js.map +1 -0
  54. package/dist/motelyBoot.d.ts +2 -0
  55. package/dist/motelyDisplay.d.ts +0 -2
  56. package/dist/r3f/Card3D.d.ts +2 -2
  57. package/dist/r3f/JimboBillboard.d.ts +1 -1
  58. package/dist/r3f.js +235 -3
  59. package/dist/r3f.js.map +1 -0
  60. package/dist/render/CanvasRenderer.d.ts +1 -1
  61. package/dist/sprites/spriteData.d.ts +1 -6
  62. package/dist/sprites/spriteMapper.d.ts +1 -1
  63. package/dist/ui/JimboBadge.d.ts +1 -1
  64. package/dist/ui/JimboFloating.d.ts +1 -1
  65. package/dist/ui/JimboIconButton.d.ts +1 -1
  66. package/dist/ui/JimboSelect.d.ts +1 -1
  67. package/dist/ui/footer.d.ts +2 -3
  68. package/dist/ui/hooks.d.ts +1 -1
  69. package/dist/ui/ide/DeckSprite.d.ts +1 -1
  70. package/dist/ui/jimbo.css +2 -1856
  71. package/dist/ui/jimboApp.d.ts +1 -1
  72. package/dist/ui/jimboFilterBar.d.ts +1 -1
  73. package/dist/ui/jimboFlankNav.d.ts +1 -1
  74. package/dist/ui/jimboInfoCard.d.ts +1 -1
  75. package/dist/ui/jimboInset.d.ts +1 -1
  76. package/dist/ui/jimboStatGrid.d.ts +1 -1
  77. package/dist/ui/jimboText.d.ts +1 -1
  78. package/dist/ui/jimboTooltip.d.ts +2 -2
  79. package/dist/ui/mascot/SeedMascot.d.ts +2 -2
  80. package/dist/ui/panel.d.ts +1 -1
  81. package/dist/ui/radial/RadialBadge.d.ts +1 -2
  82. package/dist/ui/radial/RadialButton.d.ts +1 -2
  83. package/dist/ui/radial/RadialMenu.d.ts +2 -2
  84. package/dist/ui/radial/RadialPill.d.ts +1 -2
  85. package/dist/ui/radial/index.d.ts +16 -16
  86. package/dist/ui/radial/radialMenuStore.d.ts +1 -1
  87. package/dist/ui/showcase.d.ts +1 -1
  88. package/dist/ui/sprites.d.ts +2 -2
  89. package/dist/ui.d.ts +0 -1
  90. package/dist/ui.js +3 -36
  91. package/dist/utils/gameCardUtils.d.ts +1 -1
  92. package/dist/utils/jamlVisualFilter.d.ts +1 -7
  93. package/package.json +13 -25
  94. package/dist/assets.js +0 -48
  95. package/dist/components/AnalyzerExplorer.js +0 -391
  96. package/dist/components/CardFan.js +0 -80
  97. package/dist/components/CardList.js +0 -5
  98. package/dist/components/DeckSprite.js +0 -75
  99. package/dist/components/GameCard.js +0 -355
  100. package/dist/components/JamlAestheticSelector.js +0 -22
  101. package/dist/components/JamlAnalyzerFullscreen.js +0 -263
  102. package/dist/components/JamlCodeEditor.js +0 -137
  103. package/dist/components/JamlCurator.js +0 -64
  104. package/dist/components/JamlCurator.stories.d.ts +0 -6
  105. package/dist/components/JamlCurator.stories.js +0 -14
  106. package/dist/components/JamlIde.js +0 -193
  107. package/dist/components/JamlIdeToolbar.js +0 -23
  108. package/dist/components/JamlIdeVisual.js +0 -218
  109. package/dist/components/JamlMapPreview.js +0 -121
  110. package/dist/components/JamlSeedInput.js +0 -26
  111. package/dist/components/JamlSpeedometer.js +0 -70
  112. package/dist/components/Jimbolate.js +0 -17
  113. package/dist/components/MotelyVersionBadge.js +0 -19
  114. package/dist/components/PaginatedFilterBrowser.js +0 -54
  115. package/dist/components/RunConfigModal.js +0 -59
  116. package/dist/components/Standardcard.js +0 -80
  117. package/dist/components/jamlMap/CategoryPicker.js +0 -135
  118. package/dist/components/jamlMap/JamlMapEditor.js +0 -304
  119. package/dist/components/jamlMap/JamlMapEditor.stories.d.ts +0 -7
  120. package/dist/components/jamlMap/JamlMapEditor.stories.js +0 -26
  121. package/dist/components/jamlMap/JamlMapEditorDemo.d.ts +0 -8
  122. package/dist/components/jamlMap/JamlMapEditorDemo.js +0 -323
  123. package/dist/components/jamlMap/JokerPicker.js +0 -113
  124. package/dist/components/jamlMap/MysterySlot.js +0 -128
  125. package/dist/components/jamlMap/MysterySlot.stories.d.ts +0 -7
  126. package/dist/components/jamlMap/MysterySlot.stories.js +0 -31
  127. package/dist/components/jamlMap/index.js +0 -4
  128. package/dist/decode/motelyItemDecoder.js +0 -164
  129. package/dist/decode/motelySprite.js +0 -84
  130. package/dist/hooks/analyzerStreamRegistry.js +0 -96
  131. package/dist/hooks/searchWorker.d.ts +0 -1
  132. package/dist/hooks/searchWorker.js +0 -119
  133. package/dist/hooks/searchWorkerCode.d.ts +0 -1
  134. package/dist/hooks/searchWorkerCode.js +0 -85
  135. package/dist/hooks/useAnalyzer.js +0 -91
  136. package/dist/hooks/useIntersectionObserver.js +0 -52
  137. package/dist/hooks/useSearch.js +0 -161
  138. package/dist/hooks/useShopStream.js +0 -85
  139. package/dist/lib/SpriteMapper.js +0 -48
  140. package/dist/lib/cardParser.js +0 -67
  141. package/dist/lib/classes/BuyMetaData.js +0 -1
  142. package/dist/lib/config.js +0 -15
  143. package/dist/lib/const.js +0 -521
  144. package/dist/lib/data/constants.js +0 -14
  145. package/dist/lib/hooks/useDragScroll.js +0 -48
  146. package/dist/lib/hooks/useJamlFilter.js +0 -219
  147. package/dist/lib/hooks/useSeedAnalyzer.js +0 -50
  148. package/dist/lib/jaml/jamlCompletion.js +0 -13
  149. package/dist/lib/jaml/jamlData.js +0 -6
  150. package/dist/lib/jaml/jamlObjectives.js +0 -97
  151. package/dist/lib/jaml/jamlParser.js +0 -47
  152. package/dist/lib/jaml/jamlPresets.js +0 -61
  153. package/dist/lib/jaml/jamlSchema.js +0 -91
  154. package/dist/lib/parseDailyRitual.js +0 -70
  155. package/dist/lib/tts/getRevealPos.js +0 -16
  156. package/dist/lib/tts/splitTtsDisplay.js +0 -35
  157. package/dist/lib/types.js +0 -1
  158. package/dist/lib/utils.js +0 -5
  159. package/dist/motelyDisplay.js +0 -59
  160. package/dist/r3f/Card3D.js +0 -72
  161. package/dist/r3f/JimboBillboard.js +0 -32
  162. package/dist/r3f/JimboText3D.js +0 -8
  163. package/dist/render/CanvasRenderer.js +0 -11
  164. package/dist/render/Layer.js +0 -18
  165. package/dist/sprites/spriteData.js +0 -100
  166. package/dist/sprites/spriteMapper.js +0 -75
  167. package/dist/stories/Button.d.ts +0 -15
  168. package/dist/stories/Button.js +0 -7
  169. package/dist/stories/Button.stories.d.ts +0 -24
  170. package/dist/stories/Button.stories.js +0 -50
  171. package/dist/stories/Header.d.ts +0 -12
  172. package/dist/stories/Header.js +0 -4
  173. package/dist/stories/Header.stories.d.ts +0 -18
  174. package/dist/stories/Header.stories.js +0 -26
  175. package/dist/stories/Page.d.ts +0 -3
  176. package/dist/stories/Page.js +0 -8
  177. package/dist/stories/Page.stories.d.ts +0 -12
  178. package/dist/stories/Page.stories.js +0 -24
  179. package/dist/ui/Jimbo.stories.d.ts +0 -7
  180. package/dist/ui/Jimbo.stories.js +0 -28
  181. package/dist/ui/JimboBadge.js +0 -8
  182. package/dist/ui/JimboFloating.js +0 -17
  183. package/dist/ui/JimboIconButton.js +0 -28
  184. package/dist/ui/JimboInputModal.js +0 -66
  185. package/dist/ui/JimboSelect.js +0 -43
  186. package/dist/ui/JimboToggleList.js +0 -5
  187. package/dist/ui/PanelSplitter.js +0 -78
  188. package/dist/ui/codeBlock.js +0 -14
  189. package/dist/ui/footer.js +0 -20
  190. package/dist/ui/hooks.js +0 -634
  191. package/dist/ui/ide/AgnosticSeedCard.d.ts +0 -19
  192. package/dist/ui/ide/AgnosticSeedCard.js +0 -48
  193. package/dist/ui/ide/DeckSprite.js +0 -2
  194. package/dist/ui/ide/JamlBuilder.d.ts +0 -1
  195. package/dist/ui/ide/JamlBuilder.js +0 -112
  196. package/dist/ui/ide/JamlEditor.js +0 -486
  197. package/dist/ui/ide/JamlEditorMonaco.d.ts +0 -8
  198. package/dist/ui/ide/JamlEditorMonaco.js +0 -78
  199. package/dist/ui/ide/WasmStatus.d.ts +0 -1
  200. package/dist/ui/ide/WasmStatus.js +0 -42
  201. package/dist/ui/jimboApp.js +0 -15
  202. package/dist/ui/jimboBackground.js +0 -27
  203. package/dist/ui/jimboCopyRow.js +0 -18
  204. package/dist/ui/jimboFilterBar.js +0 -16
  205. package/dist/ui/jimboFlankNav.js +0 -18
  206. package/dist/ui/jimboInfoCard.js +0 -26
  207. package/dist/ui/jimboInset.js +0 -9
  208. package/dist/ui/jimboSectionHeader.js +0 -9
  209. package/dist/ui/jimboStatGrid.js +0 -9
  210. package/dist/ui/jimboTabs.js +0 -22
  211. package/dist/ui/jimboText.js +0 -33
  212. package/dist/ui/jimboTooltip.js +0 -39
  213. package/dist/ui/jimboWordmark.js +0 -9
  214. package/dist/ui/mascot/JammySpeechBox.js +0 -30
  215. package/dist/ui/mascot/SeedMascot.js +0 -17
  216. package/dist/ui/mascot/index.js +0 -3
  217. package/dist/ui/mascot/menuConfig.js +0 -12
  218. package/dist/ui/panel.js +0 -24
  219. package/dist/ui/radial/RadialBadge.js +0 -43
  220. package/dist/ui/radial/RadialBreadcrumb.js +0 -18
  221. package/dist/ui/radial/RadialButton.js +0 -102
  222. package/dist/ui/radial/RadialMenu.js +0 -168
  223. package/dist/ui/radial/RadialPill.js +0 -15
  224. package/dist/ui/radial/index.js +0 -18
  225. package/dist/ui/radial/radialMenuStore.js +0 -122
  226. package/dist/ui/radial/radialMenuViewport.js +0 -59
  227. package/dist/ui/radial/useRadialMenu.js +0 -107
  228. package/dist/ui/showcase.js +0 -20
  229. package/dist/ui/sprites.js +0 -77
  230. package/dist/ui/tokens.js +0 -64
  231. package/dist/utils/gameCardUtils.js +0 -15
  232. package/dist/utils/jamlMapPreview.js +0 -106
  233. package/dist/utils/jamlVisualFilter.js +0 -210
@@ -1,486 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
- import { createPortal } from 'react-dom';
4
- import yaml from 'js-yaml';
5
- import { Plus, Minus, Check } from 'lucide-react';
6
- import { JamlCompletionService } from '../../lib/jaml/jamlCompletion';
7
- // Balatro Colors - High Contrast Theme
8
- const COLORS = {
9
- white: '#FFFFFF',
10
- black: '#000000',
11
- red: '#ff5e5e', // Balatro Red
12
- blue: '#4bb1ff', // Balatro Blue
13
- green: '#46bc77', // Balatro Green
14
- purple: '#9074ff', // Balatro Purple
15
- orange: '#ff9d4d', // Balatro Orange
16
- yellow: '#ffcf4d', // Balatro Yellow
17
- gold: '#efb82d',
18
- // Editor background
19
- editorBg: '#0f1416',
20
- editorBgAlt: '#1c2629',
21
- };
22
- const DEFAULT_JAML = `# My JAML Filter
23
- name: My Filter
24
- deck: Red
25
- stake: White
26
-
27
- must:
28
- - joker: Blueprint
29
- edition: Negative
30
- antes: [1, 2, 3]
31
-
32
- should:
33
- - soulJoker: Any
34
- score: 5
35
- `;
36
- const METADATA_KEYS = ['name', 'author', 'description', 'deck', 'stake', 'label'];
37
- const REQUIRED_KEYS = ['joker', 'soulJoker', 'voucher', 'tarotCard', 'planetCard', 'spectralCard', 'standardCard', 'tag', 'boss', 'event'];
38
- // --- Sub-components ---
39
- function SuggestionList({ suggestions, selectedIndex, onSelect, onHover }) {
40
- if (suggestions.length === 0) {
41
- return (_jsx("div", { className: "p-2 text-xs text-white/40 italic", children: "No suggestions..." }));
42
- }
43
- return (_jsx("div", { className: "flex flex-col max-h-[200px] overflow-y-auto", onMouseDown: e => e.preventDefault(), children: suggestions.map((s, idx) => {
44
- const isSelected = idx === selectedIndex;
45
- return (_jsxs("div", { onClick: () => onSelect(s.text), onMouseEnter: () => onHover(idx), className: `
46
- flex items-center justify-between px-3 py-1.5 cursor-pointer font-mono text-[13px] transition-colors
47
- ${isSelected ? 'bg-[var(--balatro-gold)] text-black' : 'text-white hover:bg-white/10'}
48
- `, children: [_jsx("span", { children: s.displayText }), isSelected && _jsx("span", { className: "opacity-50 text-[11px] ml-2", children: "\u21B5" })] }, `${s.text}-${idx}`));
49
- }) }));
50
- }
51
- function AntesToggle({ values, onToggle, color }) {
52
- const [expanded, setExpanded] = useState(false);
53
- const maxAnte = 8;
54
- const selectedAntes = new Set(values.map(v => parseInt(v, 10)).filter(n => !isNaN(n)));
55
- const getDisplayText = () => {
56
- if (selectedAntes.size === 0)
57
- return 'tap to select';
58
- const sorted = Array.from(selectedAntes).sort((a, b) => a - b);
59
- if (sorted.length === 1)
60
- return `Ante ${sorted[0]}`;
61
- const min = sorted[0];
62
- const max = sorted[sorted.length - 1];
63
- const isConsecutive = sorted.every((v, i) => i === 0 || v === sorted[i - 1] + 1);
64
- if (isConsecutive)
65
- return `Antes ${min}-${max}`;
66
- return `Antes ${sorted.join(', ')}`;
67
- };
68
- if (!expanded) {
69
- return (_jsx("div", { onClick: () => setExpanded(true), className: "jaml-block", style: {
70
- '--jaml-bg': selectedAntes.size > 0 ? `${color}20` : `${COLORS.red}15`,
71
- '--jaml-border': `1px solid ${selectedAntes.size > 0 ? color : COLORS.red}`,
72
- '--jaml-color': selectedAntes.size > 0 ? color : COLORS.red,
73
- '--jaml-min-w': '100px',
74
- '--jaml-shadow': selectedAntes.size > 0 ? `0 0 10px ${color}20` : 'none',
75
- }, children: getDisplayText() }));
76
- }
77
- return (_jsxs("div", { className: "flex flex-row items-center", children: [Array.from({ length: maxAnte + 1 }, (_, i) => i).map((ante) => {
78
- const isSelected = selectedAntes.has(ante);
79
- const borderRadiusClass = ante === 0 ? 'jaml-ante-btn--first' : ante === maxAnte ? 'jaml-ante-btn--last' : 'jaml-ante-btn';
80
- return (_jsx("div", { onClick: (e) => {
81
- e.stopPropagation();
82
- onToggle(ante.toString());
83
- }, className: `jaml-block ${borderRadiusClass}`, style: {
84
- '--jaml-min-w': '28px',
85
- '--jaml-bg': isSelected ? `${color}40` : 'transparent',
86
- '--jaml-border': `1px solid ${isSelected ? color : 'rgba(255,255,255,0.2)'}`,
87
- '--jaml-color': isSelected ? color : 'rgba(255,255,255,0.4)',
88
- borderRight: ante < maxAnte ? 'none' : undefined,
89
- }, children: ante }, ante));
90
- }), _jsx("div", { onClick: () => setExpanded(false), className: "jaml-block jaml-antes-confirm", children: _jsx(Check, { size: 16, strokeWidth: 3 }) })] }));
91
- }
92
- // Custom Hook for Floating Position (Viewport-aware)
93
- function useFloatingPosition(targetRef, isOpen) {
94
- const [coords, setCoords] = useState(null);
95
- useEffect(() => {
96
- if (!isOpen || !targetRef.current) {
97
- setCoords(null);
98
- return;
99
- }
100
- const updatePosition = () => {
101
- if (!targetRef.current)
102
- return;
103
- const rect = targetRef.current.getBoundingClientRect();
104
- const spaceBelow = window.innerHeight - rect.bottom;
105
- const spaceAbove = rect.top;
106
- // Prefer bottom, unless too close to edge
107
- const showBelow = spaceBelow > 220 || spaceBelow > spaceAbove;
108
- setCoords({
109
- left: rect.left,
110
- top: showBelow ? rect.bottom + 4 : rect.top - 4,
111
- position: showBelow ? 'bottom' : 'top'
112
- });
113
- };
114
- updatePosition();
115
- // Update on scroll/resize to keep pinned
116
- window.addEventListener('scroll', updatePosition, true);
117
- window.addEventListener('resize', updatePosition);
118
- return () => {
119
- window.removeEventListener('scroll', updatePosition, true);
120
- window.removeEventListener('resize', updatePosition);
121
- };
122
- }, [isOpen, targetRef]);
123
- return coords;
124
- }
125
- // --- Main Editor Component ---
126
- export default function JamlEditor({ initialJaml, onJamlChange, className }) {
127
- const [lines, setLines] = useState([]);
128
- const [editingLineId, setEditingLineId] = useState(null);
129
- const [editingPart, setEditingPart] = useState(null);
130
- const [editingArrayIndex, setEditingArrayIndex] = useState(null);
131
- const editorRef = useRef(null);
132
- // -- Parsing Logic --
133
- const parseJamlToLines = useCallback((text) => {
134
- const rawLines = text.split('\n');
135
- let currentClauseType;
136
- return rawLines.map((raw, index) => {
137
- const indent = raw.search(/\S|$/);
138
- const trimmed = raw.trim();
139
- const isComment = trimmed.startsWith('#');
140
- const isArrayItem = trimmed.startsWith('- ');
141
- let key;
142
- let value;
143
- let isArrayValue = false;
144
- let arrayValues;
145
- if (!isComment && trimmed.includes(':')) {
146
- const colonIndex = trimmed.indexOf(':');
147
- const rawKey = trimmed.slice(isArrayItem ? 2 : 0, colonIndex).trim();
148
- const rawValue = trimmed.slice(colonIndex + 1).trim();
149
- key = rawKey;
150
- value = rawValue || undefined;
151
- if (value && value.startsWith('[') && value.endsWith(']')) {
152
- isArrayValue = true;
153
- const inner = value.slice(1, -1);
154
- arrayValues = inner.split(',').map(v => v.trim()).filter(v => v);
155
- }
156
- }
157
- if (indent === 0 && !isArrayItem)
158
- currentClauseType = undefined;
159
- // Basic clause type tracking (heuristic)
160
- if (isArrayItem && key && REQUIRED_KEYS.includes(key)) {
161
- currentClauseType = key;
162
- }
163
- let validationState = 'complete';
164
- let isInvalidValue = false;
165
- if (key) {
166
- if (METADATA_KEYS.includes(key))
167
- validationState = 'metadata';
168
- else if (REQUIRED_KEYS.includes(key))
169
- validationState = value ? 'complete' : 'required-incomplete';
170
- else if (!value && key !== 'must' && key !== 'should' && key !== 'mustNot')
171
- validationState = 'optional-incomplete';
172
- if (value && value.startsWith('~') && value.endsWith('~')) {
173
- isInvalidValue = true;
174
- validationState = 'invalid';
175
- }
176
- }
177
- return {
178
- id: `line-${index}`,
179
- raw, indent, key, value, isComment, isArrayItem, lineNumber: index,
180
- clauseType: currentClauseType, validationState, isInvalidValue, isArrayValue, arrayValues
181
- };
182
- });
183
- }, []);
184
- const linesToJaml = useCallback((linesList) => linesList.map(l => l.raw).join('\n'), []);
185
- const [prevInitialJaml, setPrevInitialJaml] = useState(initialJaml);
186
- if (initialJaml !== prevInitialJaml) {
187
- setPrevInitialJaml(initialJaml);
188
- const text = initialJaml || DEFAULT_JAML;
189
- if (lines.length === 0 || linesToJaml(lines) !== text) {
190
- setLines(parseJamlToLines(text));
191
- }
192
- }
193
- const updateLineValue = useCallback((lineId, part, newValue) => {
194
- const newLines = lines.map(line => {
195
- if (line.id !== lineId)
196
- return line;
197
- const indent = ' '.repeat(line.indent);
198
- const prefix = line.isArrayItem ? '- ' : '';
199
- let newRaw = line.raw;
200
- if (part === 'value' && line.key) {
201
- newRaw = `${indent}${prefix}${line.key}: ${newValue}`;
202
- }
203
- else if (part === 'key') {
204
- const valuePart = line.value ? `: ${line.value}` : ':';
205
- newRaw = `${indent}${prefix}${newValue}${valuePart}`;
206
- }
207
- let isArrayValue = false;
208
- let arrayValues;
209
- if (newValue && newValue.startsWith('[') && newValue.endsWith(']')) {
210
- isArrayValue = true;
211
- arrayValues = newValue.slice(1, -1).split(',').map(v => v.trim()).filter(v => v);
212
- }
213
- return { ...line, raw: newRaw, [part]: newValue, isArrayValue, arrayValues };
214
- });
215
- setLines(newLines);
216
- const txt = linesToJaml(newLines);
217
- if (onJamlChange) {
218
- try {
219
- onJamlChange(txt, yaml.load(txt), true);
220
- }
221
- catch {
222
- onJamlChange(txt, null, false);
223
- }
224
- }
225
- }, [lines, linesToJaml, onJamlChange]);
226
- const updateArrayItem = useCallback((lineId, arrayIndex, newValue) => {
227
- const newLines = lines.map(line => {
228
- if (line.id !== lineId || !line.arrayValues)
229
- return line;
230
- const newArrayValues = [...line.arrayValues];
231
- newArrayValues[arrayIndex] = newValue;
232
- const newArrayStr = `[${newArrayValues.join(', ')}]`;
233
- const indent = ' '.repeat(line.indent);
234
- const prefix = line.isArrayItem ? '- ' : '';
235
- const newRaw = `${indent}${prefix}${line.key}: ${newArrayStr}`;
236
- return { ...line, raw: newRaw, value: newArrayStr, arrayValues: newArrayValues };
237
- });
238
- setLines(newLines);
239
- const txt = linesToJaml(newLines);
240
- if (onJamlChange) {
241
- try {
242
- onJamlChange(txt, yaml.load(txt), true);
243
- }
244
- catch {
245
- onJamlChange(txt, null, false);
246
- }
247
- }
248
- }, [lines, linesToJaml, onJamlChange]);
249
- const addArrayItem = useCallback((lineId, newValue) => {
250
- const newLines = lines.map(line => {
251
- if (line.id !== lineId)
252
- return line;
253
- const newArrayValues = [...(line.arrayValues || []), newValue];
254
- const newArrayStr = `[${newArrayValues.join(', ')}]`;
255
- const indent = ' '.repeat(line.indent);
256
- const prefix = line.isArrayItem ? '- ' : '';
257
- const newRaw = `${indent}${prefix}${line.key}: ${newArrayStr}`;
258
- return { ...line, raw: newRaw, value: newArrayStr, arrayValues: newArrayValues, isArrayValue: true };
259
- });
260
- setLines(newLines);
261
- const txt = linesToJaml(newLines);
262
- if (onJamlChange) {
263
- try {
264
- onJamlChange(txt, yaml.load(txt), true);
265
- }
266
- catch {
267
- onJamlChange(txt, null, false);
268
- }
269
- }
270
- }, [lines, linesToJaml, onJamlChange]);
271
- const removeArrayItem = useCallback((lineId, arrayIndex) => {
272
- const newLines = lines.map(line => {
273
- if (line.id !== lineId || !line.arrayValues)
274
- return line;
275
- const newArrayValues = line.arrayValues.filter((_, i) => i !== arrayIndex);
276
- const newArrayStr = newArrayValues.length > 0 ? `[${newArrayValues.join(', ')}]` : '';
277
- const indent = ' '.repeat(line.indent);
278
- const prefix = line.isArrayItem ? '- ' : '';
279
- const newRaw = `${indent}${prefix}${line.key}: ${newArrayStr}`;
280
- return { ...line, raw: newRaw, value: newArrayStr || undefined, arrayValues: newArrayValues.length > 0 ? newArrayValues : undefined, isArrayValue: newArrayValues.length > 0 };
281
- });
282
- setLines(newLines);
283
- const txt = linesToJaml(newLines);
284
- if (onJamlChange) {
285
- try {
286
- onJamlChange(txt, yaml.load(txt), true);
287
- }
288
- catch {
289
- onJamlChange(txt, null, false);
290
- }
291
- }
292
- }, [lines, linesToJaml, onJamlChange]);
293
- const deleteLine = useCallback((lineId) => {
294
- const filtered = lines.filter(l => l.id !== lineId);
295
- const renumbered = filtered.map((l, i) => ({ ...l, lineNumber: i, id: `line-${i}` }));
296
- setLines(renumbered);
297
- const txt = linesToJaml(renumbered);
298
- if (onJamlChange) {
299
- try {
300
- onJamlChange(txt, yaml.load(txt), true);
301
- }
302
- catch {
303
- onJamlChange(txt, null, false);
304
- }
305
- }
306
- }, [lines, linesToJaml, onJamlChange]);
307
- // -- Render --
308
- const maxKeyLengthByIndent = useMemo(() => {
309
- const byIndent = {};
310
- for (const line of lines) {
311
- if (line.key) {
312
- // Cap the alignment width at 12 characters to prevent huge gaps
313
- byIndent[line.indent] = Math.min(Math.max(byIndent[line.indent] || 0, line.key.length), 12);
314
- }
315
- }
316
- return byIndent;
317
- }, [lines]);
318
- return (_jsxs("div", { ref: editorRef, className: `flex flex-col bg-[#0f1416] text-white font-mono text-[13px] leading-[1.8] outline-none rounded-md p-4 overflow-auto min-h-[500px] border border-white/5 ${className}`, tabIndex: 0, children: [_jsx("div", { className: "flex flex-col gap-0.5", children: lines.map((line) => (_jsx(JamlLine, { line: line, keyWidth: maxKeyLengthByIndent[line.indent] || 8, isEditing: editingLineId === line.id, editingPart: editingLineId === line.id ? editingPart : null, editingArrayIndex: editingLineId === line.id ? editingArrayIndex : null, onStartEdit: (part, idx) => {
319
- setEditingLineId(line.id);
320
- setEditingPart(part);
321
- setEditingArrayIndex(idx ?? null);
322
- }, onEndEdit: () => {
323
- setEditingLineId(null);
324
- setEditingPart(null);
325
- setEditingArrayIndex(null);
326
- }, onChange: (part, val) => updateLineValue(line.id, part, val), onArrayItemChange: (idx, val) => updateArrayItem(line.id, idx, val), onArrayItemAdd: (val) => addArrayItem(line.id, val), onArrayItemRemove: (idx) => removeArrayItem(line.id, idx), onDelete: () => deleteLine(line.id) }, line.id))) }), _jsxs("div", { className: "mt-4 p-2 bg-black/40 rounded border border-white/5 flex flex-wrap gap-4 text-[12px] text-white/50 font-mono", children: [_jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "jaml-legend-dot jaml-legend-dot--red" }), " required"] }), _jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "jaml-legend-dot jaml-legend-dot--blue" }), " optional"] }), _jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "jaml-legend-dot jaml-legend-dot--green" }), " complete"] }), _jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "jaml-legend-dot jaml-legend-dot--purple" }), " metadata"] }), _jsx("span", { className: "ml-auto opacity-40", children: "Click to edit \u2022 Tab to navigate" })] })] }));
327
- }
328
- function JamlLine({ line, keyWidth, isEditing, editingPart, editingArrayIndex, onStartEdit, onEndEdit, onChange, onArrayItemChange, onArrayItemAdd, onArrayItemRemove, onDelete }) {
329
- const [selectedIndex, setSelectedIndex] = useState(0);
330
- const [localValue, setLocalValue] = useState('');
331
- const [prevContext, setPrevContext] = useState('');
332
- const [prevEditState, setPrevEditState] = useState({ isEditing, editingPart, editingArrayIndex, lineRaw: line.raw });
333
- if (isEditing !== prevEditState.isEditing ||
334
- editingPart !== prevEditState.editingPart ||
335
- editingArrayIndex !== prevEditState.editingArrayIndex ||
336
- line.raw !== prevEditState.lineRaw) {
337
- setPrevEditState({ isEditing, editingPart, editingArrayIndex, lineRaw: line.raw });
338
- if (isEditing) {
339
- if (editingPart === 'key')
340
- setLocalValue(line.key || '');
341
- else if (editingPart === 'value')
342
- setLocalValue((line.value || '').replace(/^~|~$/g, ''));
343
- else if (editingPart === 'arrayItem' && editingArrayIndex !== null)
344
- setLocalValue(line.arrayValues?.[editingArrayIndex] || '');
345
- else
346
- setLocalValue('');
347
- }
348
- }
349
- const currentContext = useMemo(() => {
350
- if (!isEditing || !editingPart)
351
- return '';
352
- if (editingPart === 'value' && line.key) {
353
- return `${line.key}: ${localValue}`;
354
- }
355
- else if (editingPart === 'key') {
356
- return localValue;
357
- }
358
- return line.raw;
359
- }, [isEditing, editingPart, localValue, line.raw, line.key]);
360
- const suggestions = useMemo(() => {
361
- if (!currentContext)
362
- return [];
363
- return JamlCompletionService.getCompletions(currentContext).slice(0, 10);
364
- }, [currentContext]);
365
- if (currentContext !== prevContext) {
366
- setPrevContext(currentContext);
367
- setSelectedIndex(0);
368
- }
369
- const inputRef = useRef(null);
370
- const targetRef = useRef(null);
371
- const floatingCoords = useFloatingPosition(targetRef, isEditing && suggestions.length > 0);
372
- // Colors
373
- const getBaseColor = () => {
374
- switch (line.validationState) {
375
- case 'required-incomplete': return COLORS.red;
376
- case 'optional-incomplete': return COLORS.blue;
377
- case 'complete': return COLORS.green;
378
- case 'invalid': return COLORS.red;
379
- case 'metadata': return COLORS.purple;
380
- default: return '#888';
381
- }
382
- };
383
- const getBrightColor = () => {
384
- switch (line.validationState) {
385
- case 'required-incomplete': return COLORS.red;
386
- case 'optional-incomplete': return COLORS.blue;
387
- case 'complete': return COLORS.green;
388
- case 'invalid': return COLORS.red;
389
- case 'metadata': return COLORS.purple;
390
- default: return '#FFF';
391
- }
392
- };
393
- // Suggestions Logic derived above
394
- // Input Focus
395
- useEffect(() => {
396
- if (isEditing && inputRef.current) {
397
- inputRef.current.focus();
398
- }
399
- }, [isEditing]);
400
- const handleKeyDown = (e) => {
401
- if (e.key === 'Enter') {
402
- e.preventDefault();
403
- const finalVal = (suggestions.length > 0 && selectedIndex >= 0) ? suggestions[selectedIndex].text : localValue;
404
- if (editingPart === 'key')
405
- onChange('key', finalVal);
406
- else if (editingPart === 'value')
407
- onChange('value', finalVal);
408
- else if (editingPart === 'arrayItem') {
409
- if (editingArrayIndex >= (line.arrayValues?.length || 0))
410
- onArrayItemAdd(finalVal);
411
- else
412
- onArrayItemChange(editingArrayIndex, finalVal);
413
- }
414
- onEndEdit();
415
- }
416
- else if (e.key === 'ArrowDown') {
417
- e.preventDefault();
418
- setSelectedIndex(Math.min(selectedIndex + 1, suggestions.length - 1));
419
- }
420
- else if (e.key === 'ArrowUp') {
421
- e.preventDefault();
422
- setSelectedIndex(Math.max(selectedIndex - 1, 0));
423
- }
424
- else if (e.key === 'Escape') {
425
- onEndEdit();
426
- }
427
- else if (e.key === 'Backspace' && localValue === '' && editingPart === 'arrayItem') {
428
- onArrayItemRemove(editingArrayIndex);
429
- onEndEdit();
430
- }
431
- };
432
- if (line.isComment) {
433
- return _jsx("div", { className: "pl-8 text-stone-400 italic text-xs py-0.5", children: line.raw });
434
- }
435
- if (!line.key && !line.raw.trim()) {
436
- return _jsx("div", { className: "h-5" });
437
- }
438
- if ((line.key === 'must' || line.key === 'should' || line.key === 'mustNot') && !line.value) {
439
- const color = line.key === 'must' ? COLORS.red : COLORS.blue;
440
- return _jsx("div", { className: "jaml-clause-header pl-8 py-1 text-[16px] border-b border-white/10 mt-4 mb-2 uppercase tracking-widest", style: { '--jaml-color': color }, children: line.raw });
441
- }
442
- const indentSpaces = ' '.repeat(line.indent);
443
- const prefix = line.isArrayItem ? '- ' : '';
444
- // Helper: popover CSS vars from floating coords
445
- const popoverVars = floatingCoords ? {
446
- '--popover-top': `${floatingCoords.top}px`,
447
- '--popover-left': `${floatingCoords.left}px`,
448
- '--popover-transform': floatingCoords.position === 'top' ? 'translateY(-100%)' : 'none',
449
- } : {};
450
- return (_jsxs("div", { className: "relative flex items-center py-0.5 group", children: [_jsx("div", { className: "w-6 h-full flex items-center justify-center cursor-pointer opacity-0 group-hover:opacity-100 transition-opacity", onClick: (e) => { e.stopPropagation(); onDelete(); }, children: _jsx(Minus, { size: 12, className: "text-orange-500 hover:bg-orange-100 rounded" }) }), _jsxs("span", { className: "whitespace-pre text-stone-400", children: [indentSpaces, prefix] }), line.key && (_jsxs("div", { className: "relative", children: [_jsx("div", { ref: editingPart === 'key' ? targetRef : null, onClick: (e) => { e.stopPropagation(); onStartEdit('key'); }, className: "jaml-block jaml-block--start", style: {
451
- '--jaml-min-w': `${keyWidth}ch`,
452
- '--jaml-color': (isEditing && editingPart === 'key') ? getBrightColor() : getBaseColor(),
453
- '--jaml-bg': (isEditing && editingPart === 'key') ? `${getBrightColor()}15` : 'transparent',
454
- }, children: isEditing && editingPart === 'key' ? (_jsx("input", { ref: inputRef, title: "Edit key", value: localValue, onChange: e => setLocalValue(e.target.value), onKeyDown: handleKeyDown, onBlur: () => setTimeout(onEndEdit, 200), className: "jaml-inline-input", style: { '--jaml-color': getBrightColor() } })) : line.key }), isEditing && editingPart === 'key' && suggestions.length > 0 && floatingCoords && createPortal(_jsx("div", { className: "jaml-suggestion-popover", style: popoverVars, children: _jsx(SuggestionList, { suggestions: suggestions, selectedIndex: selectedIndex, onHover: setSelectedIndex, onSelect: (val) => {
455
- onChange('key', val);
456
- onEndEdit();
457
- } }) }), document.body)] })), line.key && _jsx("span", { className: "text-stone-400 mr-1", children: ":" }), line.key && (line.isArrayValue && line.arrayValues ? (line.key === 'antes' ? (_jsx(AntesToggle, { values: line.arrayValues, onToggle: (val) => {
458
- const idx = line.arrayValues.indexOf(val);
459
- if (idx >= 0)
460
- onArrayItemRemove(idx);
461
- else
462
- onArrayItemAdd(val);
463
- }, color: getBrightColor() })) : (_jsxs("div", { className: "flex gap-0.5 items-center", children: [line.arrayValues.map((val, idx) => (_jsx("div", { onClick: (e) => { e.stopPropagation(); onStartEdit('arrayItem', idx); }, className: "jaml-block", style: {
464
- '--jaml-min-w': '24px',
465
- '--jaml-bg': `${getBaseColor()}15`,
466
- '--jaml-border': `1px solid ${getBaseColor()}40`,
467
- '--jaml-color': getBaseColor(),
468
- }, children: isEditing && editingPart === 'arrayItem' && editingArrayIndex === idx ? (_jsx("input", { ref: inputRef, title: "Edit array item", value: localValue, onChange: e => setLocalValue(e.target.value), onKeyDown: handleKeyDown, onBlur: () => setTimeout(onEndEdit, 200), className: "bg-transparent w-[3ch] text-center outline-none" })) : val }, idx))), _jsx("div", { onClick: (e) => { e.stopPropagation(); onStartEdit('arrayItem', line.arrayValues.length); }, className: "jaml-block", style: {
469
- '--jaml-min-w': '24px',
470
- '--jaml-bg': `${COLORS.green}15`,
471
- '--jaml-border': `1px solid ${COLORS.green}40`,
472
- '--jaml-color': COLORS.green,
473
- }, children: _jsx(Plus, { size: 12 }) })] }))) : (_jsxs("div", { className: "relative", children: [_jsx("div", { ref: editingPart === 'value' ? targetRef : null, onClick: (e) => { e.stopPropagation(); onStartEdit('value'); }, className: "jaml-block", style: {
474
- '--jaml-min-w': line.value ? undefined : '60px',
475
- '--jaml-color': line.isInvalidValue ? COLORS.red : (line.value ? getBaseColor() : COLORS.red),
476
- '--jaml-bg': line.isInvalidValue ? `${COLORS.red}15` : (line.value ? `${getBaseColor()}10` : `${COLORS.red}08`),
477
- '--jaml-border': `1px solid ${line.isInvalidValue ? `${COLORS.red}60` : (line.value ? `${getBaseColor()}40` : `${COLORS.red}40`)}`,
478
- '--jaml-text-decoration': line.isInvalidValue ? 'line-through' : 'none',
479
- }, children: isEditing && editingPart === 'value' ? (_jsx("input", { ref: inputRef, title: "Edit value", value: localValue, onChange: e => setLocalValue(e.target.value), onKeyDown: handleKeyDown, onBlur: () => setTimeout(onEndEdit, 200), className: "jaml-inline-input jaml-inline-input--sized", style: {
480
- '--jaml-color': getBaseColor(),
481
- '--jaml-input-w': `${Math.max(localValue.length, 4)}ch`,
482
- } })) : (line.isInvalidValue ? line.value?.replace(/~/g, '') : (line.value || '???')) }), isEditing && editingPart === 'value' && suggestions.length > 0 && floatingCoords && createPortal(_jsx("div", { className: "jaml-suggestion-popover", style: popoverVars, children: _jsx(SuggestionList, { suggestions: suggestions, selectedIndex: selectedIndex, onHover: setSelectedIndex, onSelect: (val) => {
483
- onChange('value', val);
484
- onEndEdit();
485
- } }) }), document.body)] })))] }));
486
- }
@@ -1,8 +0,0 @@
1
- interface JamlEditorMonacoProps {
2
- value: string;
3
- onChange: (value: string | undefined) => void;
4
- diagnostics?: any;
5
- className?: string;
6
- }
7
- export default function JamlEditorMonaco({ value, onChange, diagnostics, className }: JamlEditorMonacoProps): import("react/jsx-runtime").JSX.Element;
8
- export {};
@@ -1,78 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useRef } from 'react';
4
- import Editor from "@monaco-editor/react";
5
- import { Copy, Check, AlertCircle } from 'lucide-react';
6
- import { cn } from '../../lib/utils';
7
- export default function JamlEditorMonaco({ value, onChange, diagnostics, className }) {
8
- const editorRef = useRef(null);
9
- const handleEditorWillMount = (monaco) => {
10
- // Define Balatro Theme
11
- monaco.editor.defineTheme('balatro-dark', {
12
- base: 'vs-dark',
13
- inherit: true,
14
- rules: [
15
- { token: 'comment', foreground: '5f7377', fontStyle: 'italic' },
16
- { token: 'keyword', foreground: 'fe5f55' }, // Balatro Red
17
- { token: 'string', foreground: 'eac058' }, // Balatro Gold
18
- { token: 'number', foreground: '009dff' }, // Balatro Blue
19
- { token: 'type', foreground: '4bc292' }, // Balatro Green
20
- ],
21
- colors: {
22
- 'editor.background': '#1e2b2d', // Authentic G.C.BLACK variant
23
- 'editor.foreground': '#ffffff',
24
- 'editorLineNumber.foreground': '#4f6367',
25
- 'editorLineNumber.activeForeground': '#eac058',
26
- 'editor.selectionBackground': '#ffffff20',
27
- 'editor.inactiveSelectionBackground': '#ffffff10',
28
- 'editor.lineHighlightBackground': '#00000020',
29
- 'editorCursor.foreground': '#eac058',
30
- // Widget/Popover Colors (Fixes User Issue: "White text on white background")
31
- 'editorWidget.background': '#1e2b2d', // Balatro Dark
32
- 'editorWidget.border': '#ffffff20',
33
- 'editorWidget.foreground': '#ffffff',
34
- // Suggestion List Colors
35
- 'list.activeSelectionBackground': '#d8b97d', // Balatro Gold Selection
36
- 'list.activeSelectionForeground': '#1e2b2d', // Dark text on gold
37
- 'list.hoverBackground': '#2a3b3d',
38
- 'list.hoverForeground': '#ffffff',
39
- 'list.focusBackground': '#d8b97d',
40
- 'list.focusForeground': '#1e2b2d',
41
- }
42
- });
43
- };
44
- const handleEditorDidMount = (editor, monaco) => {
45
- editorRef.current = editor;
46
- // Focus editor
47
- editor.focus();
48
- // Optional: Add custom JAML commands/actions here
49
- };
50
- const handleFormat = () => {
51
- if (editorRef.current) {
52
- editorRef.current.getAction('editor.action.formatDocument').run();
53
- }
54
- };
55
- const handleCopy = () => {
56
- navigator.clipboard.writeText(value);
57
- };
58
- const hasErrors = diagnostics?.errors?.length > 0;
59
- return (_jsxs("div", { className: cn("flex flex-col h-full bg-[#1e2b2d] border border-white/10 rounded-xl overflow-hidden shadow-2xl group", className), children: [_jsxs("div", { className: "h-10 bg-black/40 border-b border-white/5 flex items-center justify-between px-4 shrink-0 overflow-hidden", children: [_jsxs("div", { className: "flex items-center gap-4", children: [_jsxs("span", { className: "font-header text-xs text-[var(--balatro-red)] tracking-widest uppercase flex items-center gap-2", children: [_jsx("div", { className: "w-2 h-2 rounded-full bg-[var(--balatro-red)] animate-pulse" }), "JAML EDITOR"] }), _jsx("div", { className: "h-4 w-px bg-white/10" }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("button", { onClick: handleFormat, className: "text-[9px] font-pixel text-white/30 hover:text-white/80 uppercase tracking-tighter transition-colors", children: "Format" }), _jsxs("button", { onClick: handleCopy, className: "text-[9px] font-pixel text-white/30 hover:text-white/80 uppercase tracking-tighter transition-colors flex items-center gap-1", children: [_jsx(Copy, { size: 10 }), " Copy"] })] })] }), _jsx("div", { className: "flex items-center gap-2", children: hasErrors ? (_jsxs("div", { className: "flex items-center gap-1.5 px-2 py-0.5 bg-red-500/10 border border-red-500/20 rounded text-[9px] font-pixel text-red-400", children: [_jsx(AlertCircle, { size: 10 }), _jsxs("span", { children: [diagnostics.errors.length, " SYNTAX ERROR(S)"] })] })) : (_jsxs("div", { className: "flex items-center gap-1.5 px-2 py-0.5 bg-green-500/10 border border-green-500/20 rounded text-[9px] font-pixel text-green-400 opacity-60", children: [_jsx(Check, { size: 10 }), _jsx("span", { children: "SYNTAX VALID" })] })) })] }), _jsx("div", { className: "flex-1 min-h-0 relative", children: _jsx(Editor, { height: "100%", defaultLanguage: "yaml", value: value, theme: "balatro-dark", onChange: onChange, onMount: handleEditorDidMount, beforeMount: handleEditorWillMount, options: {
60
- minimap: { enabled: false },
61
- scrollBeyondLastLine: false,
62
- fontSize: 14,
63
- fontFamily: 'var(--font-mono)',
64
- lineNumbers: 'on',
65
- roundedSelection: true,
66
- readOnly: false,
67
- cursorStyle: 'line',
68
- automaticLayout: true,
69
- padding: { top: 16, bottom: 16 },
70
- wordWrap: 'on',
71
- formatOnPaste: true,
72
- formatOnType: true,
73
- suggest: {
74
- showKeywords: true,
75
- showSnippets: true,
76
- }
77
- } }) }), _jsxs("div", { className: "h-6 bg-black/20 border-t border-white/5 flex items-center px-4 justify-between shrink-0", children: [_jsxs("div", { className: "text-[8px] font-pixel text-white/20 uppercase", children: ["Lines: ", value.split('\n').length, " | Encoding: UTF-8"] }), _jsx("div", { className: "text-[8px] font-pixel text-white/20 uppercase tracking-widest", children: "Motely JAML Engine v1.0.4" })] })] }));
78
- }
@@ -1 +0,0 @@
1
- export declare function WasmStatus(): import("react/jsx-runtime").JSX.Element;
@@ -1,42 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useEffect, useState } from 'react';
4
- import motely, { Motely } from 'motely-wasm';
5
- import { Cpu, Loader2, CheckCircle2, XCircle } from 'lucide-react';
6
- import { cn } from '../../lib/utils';
7
- export function WasmStatus() {
8
- const [status, setStatus] = useState('idle');
9
- const [version, setVersion] = useState(null);
10
- const [error, setError] = useState(null);
11
- useEffect(() => {
12
- let cancelled = false;
13
- const load = async () => {
14
- setStatus('loading');
15
- try {
16
- await motely.boot();
17
- if (cancelled)
18
- return;
19
- setVersion(Motely.MotelyWasm.getVersion());
20
- setStatus('ready');
21
- }
22
- catch (err) {
23
- console.error("WASM Status Error:", err);
24
- if (cancelled)
25
- return;
26
- setStatus('error');
27
- setError(err.message || String(err));
28
- }
29
- };
30
- load();
31
- return () => {
32
- cancelled = true;
33
- };
34
- }, []);
35
- const displayVersion = version;
36
- return (_jsxs("div", { className: cn("fixed bottom-10 right-10 z-[100] flex items-center gap-3 px-4 py-2 rounded-full border shadow-2xl backdrop-blur-md transition-all", status === 'ready' ? "bg-green-500/10 border-green-500/50 text-green-400" :
37
- status === 'error' ? "bg-red-500/10 border-red-500/50 text-red-400" :
38
- "bg-blue-500/10 border-blue-500/50 text-blue-400"), children: [status === 'loading' ? _jsx(Loader2, { size: 16, className: "animate-spin" }) :
39
- status === 'ready' ? _jsx(CheckCircle2, { size: 16 }) :
40
- status === 'error' ? _jsx(XCircle, { size: 16 }) :
41
- _jsx(Cpu, { size: 16 }), _jsxs("div", { className: "flex flex-col", children: [_jsxs("span", { className: "text-[12px] uppercase tracking-widest leading-tight", children: ["WASM: ", status.toUpperCase()] }), displayVersion && (_jsxs("span", { className: "text-[11px] opacity-70 leading-tight", children: ["v", displayVersion] })), error && _jsx("span", { className: "text-[11px] opacity-70 truncate max-w-[200px] leading-tight", children: error })] })] }));
42
- }
@@ -1,15 +0,0 @@
1
- 'use client';
2
- import { jsx as _jsx } from "react/jsx-runtime";
3
- /** Standard mobile-first app shell. 320px locked, or fluid for MCP/desktop. */
4
- export function JimboApp({ children, fluid, className = '', ...props }) {
5
- const classes = `j-app${fluid ? ' j-app--fluid' : ''} ${className}`.trim();
6
- return (_jsx("div", { className: classes, ...props, children: children }));
7
- }
8
- /** Scrollable content area inside JimboApp. Hidden scrollbar, snap-friendly. */
9
- export function JimboAppScroll({ children, className = '', ...props }) {
10
- return (_jsx("div", { className: `j-app__scroll ${className}`, ...props, children: children }));
11
- }
12
- /** Sticky bottom action area inside JimboApp. Thumb zone. */
13
- export function JimboAppFooter({ children, className = '', ...props }) {
14
- return (_jsx("div", { className: `j-app__footer ${className}`, ...props, children: children }));
15
- }