jaml-ui 0.22.5 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DESIGN.md +236 -236
- package/README.md +147 -147
- package/dist/components/JamlCodeEditor.d.ts +1 -1
- package/dist/components/JamlCodeEditor.js +112 -113
- package/dist/hooks/searchWorkerCode.js +84 -84
- package/dist/hooks/useSearch.js +86 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/ui/footer.js +5 -5
- package/dist/ui/hooks.js +55 -55
- package/package.json +147 -145
package/README.md
CHANGED
|
@@ -1,147 +1,147 @@
|
|
|
1
|
-
# jaml-ui
|
|
2
|
-
|
|
3
|
-
React components, UI tokens, sprites, and utilities for Balatro/JAML apps.
|
|
4
|
-
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install jaml-ui react react-dom
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Package exports
|
|
12
|
-
|
|
13
|
-
| Entry | Contents |
|
|
14
|
-
|-------|----------|
|
|
15
|
-
| `jaml-ui` | Game card components, JAML IDE, Analyzer Explorer, hooks |
|
|
16
|
-
| `jaml-ui/ui` | Jimbo design system — JimboPanel, JimboButton, JimboModal, tokens |
|
|
17
|
-
| `jaml-ui/core` | Pure asset helpers, sprite metadata, decode utilities (no React) |
|
|
18
|
-
| `jaml-ui/motely` | motely-wasm decode helpers (requires `motely-wasm` peer) |
|
|
19
|
-
| `jaml-ui/r3f` | 3D card component via React Three Fiber (requires r3f peers) |
|
|
20
|
-
|
|
21
|
-
## Quick start
|
|
22
|
-
|
|
23
|
-
```tsx
|
|
24
|
-
import { JamlGameCard, AnalyzerExplorer, JamlIde } from "jaml-ui";
|
|
25
|
-
import { JimboPanel, JimboButton } from "jaml-ui/ui";
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
### Game card
|
|
29
|
-
|
|
30
|
-
```tsx
|
|
31
|
-
import { JamlGameCard } from "jaml-ui";
|
|
32
|
-
|
|
33
|
-
<JamlGameCard
|
|
34
|
-
type="joker"
|
|
35
|
-
card={{ name: "Blueprint", edition: "Foil", isEternal: true, scale: 1.5 }}
|
|
36
|
-
/>
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
### Jimbo UI (Balatro design system)
|
|
40
|
-
|
|
41
|
-
```tsx
|
|
42
|
-
import { JimboPanel, JimboButton, JimboModal } from "jaml-ui/ui";
|
|
43
|
-
import { JimboColorOption } from "jaml-ui/ui";
|
|
44
|
-
|
|
45
|
-
<JimboPanel sway onBack={() => setOpen(false)}>
|
|
46
|
-
<JimboButton variant="primary" onClick={handleSearch}>Search</JimboButton>
|
|
47
|
-
</JimboPanel>
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
Available variants: `primary`, `secondary`, `danger`, `back`, `ghost`
|
|
51
|
-
|
|
52
|
-
### JAML IDE
|
|
53
|
-
|
|
54
|
-
```tsx
|
|
55
|
-
import { JamlIde } from "jaml-ui";
|
|
56
|
-
|
|
57
|
-
<JamlIde
|
|
58
|
-
jaml={jaml}
|
|
59
|
-
onChange={setJaml}
|
|
60
|
-
searchResults={results}
|
|
61
|
-
onSearch={handleSearch}
|
|
62
|
-
isSearching={isSearching}
|
|
63
|
-
/>
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### Analyzer Explorer
|
|
67
|
-
|
|
68
|
-
```tsx
|
|
69
|
-
import { AnalyzerExplorer } from "jaml-ui";
|
|
70
|
-
|
|
71
|
-
// antes: AnalyzerAnteView[] — stream from motely-wasm createSearchContext
|
|
72
|
-
<AnalyzerExplorer antes={antes} totalAntes={8} highlights={highlights} />
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### JAML Map Preview
|
|
76
|
-
|
|
77
|
-
```tsx
|
|
78
|
-
import { JamlMapPreview } from "jaml-ui";
|
|
79
|
-
|
|
80
|
-
<JamlMapPreview jaml={jaml} />
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
## Asset handling
|
|
84
|
-
|
|
85
|
-
By default sprites resolve from the package `assets/` directory via `import.meta.url`.
|
|
86
|
-
|
|
87
|
-
Override at app startup:
|
|
88
|
-
|
|
89
|
-
```ts
|
|
90
|
-
import { setJamlAssetBaseUrl, clearJamlAssetBaseUrl } from "jaml-ui";
|
|
91
|
-
|
|
92
|
-
setJamlAssetBaseUrl("/vendor/jaml-ui/"); // custom CDN
|
|
93
|
-
clearJamlAssetBaseUrl(); // back to default
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
## Core utilities
|
|
97
|
-
|
|
98
|
-
```ts
|
|
99
|
-
import { SPRITE_SHEETS, getSpriteData, resolveJamlAssetUrl } from "jaml-ui/core";
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
## Motely decode helpers
|
|
103
|
-
|
|
104
|
-
```ts
|
|
105
|
-
import { decodeMotelyItemName, motelyItemTypeName } from "jaml-ui/motely";
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
## 3D card (optional)
|
|
109
|
-
|
|
110
|
-
```bash
|
|
111
|
-
npm install three @react-three/fiber @react-three/drei @react-spring/three
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
```tsx
|
|
115
|
-
import { Card3D } from "jaml-ui/r3f";
|
|
116
|
-
|
|
117
|
-
<Card3D itemName="Blueprint" />
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
## Next.js
|
|
121
|
-
|
|
122
|
-
Import pure helpers from `jaml-ui/core` for server components. For local workspace installs add:
|
|
123
|
-
|
|
124
|
-
```ts
|
|
125
|
-
// next.config.ts
|
|
126
|
-
const nextConfig = { transpilePackages: ["jaml-ui"] };
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
## Search Worker Architecture
|
|
130
|
-
|
|
131
|
-
The library provides `useAnalyzer` to interact with `motely-wasm`'s search context natively.
|
|
132
|
-
**Important:** As of `motely-wasm@14.3.3`, the search worker utilizes Vite's `?worker&inline` pattern. You no longer need to pass `motelyWasmUrl`.
|
|
133
|
-
|
|
134
|
-
Ensure `motely-wasm` is imported and booted at the module level in your application:
|
|
135
|
-
|
|
136
|
-
```tsx
|
|
137
|
-
import { boot } from "motely-wasm";
|
|
138
|
-
boot(); // Call early in your application lifecycle
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
## Peer dependencies
|
|
142
|
-
|
|
143
|
-
| Peer | Required for |
|
|
144
|
-
|------|-------------|
|
|
145
|
-
| `react`, `react-dom` | All components |
|
|
146
|
-
| `motely-wasm ^14.3.3` | `jaml-ui/motely`, `AnalyzerExplorer`, `useAnalyzer` data |
|
|
147
|
-
| `three`, `@react-three/fiber`, `@react-three/drei`, `@react-spring/three` | `jaml-ui/r3f` only |
|
|
1
|
+
# jaml-ui
|
|
2
|
+
|
|
3
|
+
React components, UI tokens, sprites, and utilities for Balatro/JAML apps.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install jaml-ui react react-dom
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Package exports
|
|
12
|
+
|
|
13
|
+
| Entry | Contents |
|
|
14
|
+
|-------|----------|
|
|
15
|
+
| `jaml-ui` | Game card components, JAML IDE, Analyzer Explorer, hooks |
|
|
16
|
+
| `jaml-ui/ui` | Jimbo design system — JimboPanel, JimboButton, JimboModal, tokens |
|
|
17
|
+
| `jaml-ui/core` | Pure asset helpers, sprite metadata, decode utilities (no React) |
|
|
18
|
+
| `jaml-ui/motely` | motely-wasm decode helpers (requires `motely-wasm` peer) |
|
|
19
|
+
| `jaml-ui/r3f` | 3D card component via React Three Fiber (requires r3f peers) |
|
|
20
|
+
|
|
21
|
+
## Quick start
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { JamlGameCard, AnalyzerExplorer, JamlIde } from "jaml-ui";
|
|
25
|
+
import { JimboPanel, JimboButton } from "jaml-ui/ui";
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Game card
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
import { JamlGameCard } from "jaml-ui";
|
|
32
|
+
|
|
33
|
+
<JamlGameCard
|
|
34
|
+
type="joker"
|
|
35
|
+
card={{ name: "Blueprint", edition: "Foil", isEternal: true, scale: 1.5 }}
|
|
36
|
+
/>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Jimbo UI (Balatro design system)
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import { JimboPanel, JimboButton, JimboModal } from "jaml-ui/ui";
|
|
43
|
+
import { JimboColorOption } from "jaml-ui/ui";
|
|
44
|
+
|
|
45
|
+
<JimboPanel sway onBack={() => setOpen(false)}>
|
|
46
|
+
<JimboButton variant="primary" onClick={handleSearch}>Search</JimboButton>
|
|
47
|
+
</JimboPanel>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Available variants: `primary`, `secondary`, `danger`, `back`, `ghost`
|
|
51
|
+
|
|
52
|
+
### JAML IDE
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
import { JamlIde } from "jaml-ui";
|
|
56
|
+
|
|
57
|
+
<JamlIde
|
|
58
|
+
jaml={jaml}
|
|
59
|
+
onChange={setJaml}
|
|
60
|
+
searchResults={results}
|
|
61
|
+
onSearch={handleSearch}
|
|
62
|
+
isSearching={isSearching}
|
|
63
|
+
/>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Analyzer Explorer
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
import { AnalyzerExplorer } from "jaml-ui";
|
|
70
|
+
|
|
71
|
+
// antes: AnalyzerAnteView[] — stream from motely-wasm createSearchContext
|
|
72
|
+
<AnalyzerExplorer antes={antes} totalAntes={8} highlights={highlights} />
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### JAML Map Preview
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
import { JamlMapPreview } from "jaml-ui";
|
|
79
|
+
|
|
80
|
+
<JamlMapPreview jaml={jaml} />
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Asset handling
|
|
84
|
+
|
|
85
|
+
By default sprites resolve from the package `assets/` directory via `import.meta.url`.
|
|
86
|
+
|
|
87
|
+
Override at app startup:
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
import { setJamlAssetBaseUrl, clearJamlAssetBaseUrl } from "jaml-ui";
|
|
91
|
+
|
|
92
|
+
setJamlAssetBaseUrl("/vendor/jaml-ui/"); // custom CDN
|
|
93
|
+
clearJamlAssetBaseUrl(); // back to default
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Core utilities
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
import { SPRITE_SHEETS, getSpriteData, resolveJamlAssetUrl } from "jaml-ui/core";
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Motely decode helpers
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
import { decodeMotelyItemName, motelyItemTypeName } from "jaml-ui/motely";
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## 3D card (optional)
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
npm install three @react-three/fiber @react-three/drei @react-spring/three
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
import { Card3D } from "jaml-ui/r3f";
|
|
116
|
+
|
|
117
|
+
<Card3D itemName="Blueprint" />
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Next.js
|
|
121
|
+
|
|
122
|
+
Import pure helpers from `jaml-ui/core` for server components. For local workspace installs add:
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
// next.config.ts
|
|
126
|
+
const nextConfig = { transpilePackages: ["jaml-ui"] };
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Search Worker Architecture
|
|
130
|
+
|
|
131
|
+
The library provides `useAnalyzer` to interact with `motely-wasm`'s search context natively.
|
|
132
|
+
**Important:** As of `motely-wasm@14.3.3`, the search worker utilizes Vite's `?worker&inline` pattern. You no longer need to pass `motelyWasmUrl`.
|
|
133
|
+
|
|
134
|
+
Ensure `motely-wasm` is imported and booted at the module level in your application:
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
import { boot } from "motely-wasm";
|
|
138
|
+
boot(); // Call early in your application lifecycle
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Peer dependencies
|
|
142
|
+
|
|
143
|
+
| Peer | Required for |
|
|
144
|
+
|------|-------------|
|
|
145
|
+
| `react`, `react-dom` | All components |
|
|
146
|
+
| `motely-wasm ^14.3.3` | `jaml-ui/motely`, `AnalyzerExplorer`, `useAnalyzer` data |
|
|
147
|
+
| `three`, `@react-three/fiber`, `@react-three/drei`, `@react-spring/three` | `jaml-ui/r3f` only |
|
|
@@ -4,4 +4,4 @@ export interface JamlCodeEditorProps {
|
|
|
4
4
|
placeholder?: string;
|
|
5
5
|
minHeight?: number;
|
|
6
6
|
}
|
|
7
|
-
export declare function JamlCodeEditor({ value, onChange, minHeight, }: JamlCodeEditorProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare function JamlCodeEditor({ value, onChange, placeholder, minHeight, }: JamlCodeEditorProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,102 +1,131 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useRef } from "react";
|
|
4
|
-
import
|
|
4
|
+
import { EditorView, keymap, lineNumbers, highlightActiveLine, drawSelection, placeholder as cmPlaceholder } from "@codemirror/view";
|
|
5
|
+
import { EditorState } from "@codemirror/state";
|
|
6
|
+
import { yaml } from "@codemirror/lang-yaml";
|
|
7
|
+
import { defaultKeymap, history, historyKeymap, indentWithTab } from "@codemirror/commands";
|
|
8
|
+
import { syntaxHighlighting, HighlightStyle } from "@codemirror/language";
|
|
9
|
+
import { tags } from "@lezer/highlight";
|
|
5
10
|
import { JimboColorOption } from "../ui/tokens.js";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
11
|
+
const balatroHighlight = HighlightStyle.define([
|
|
12
|
+
{ tag: tags.comment, color: JimboColorOption.GREY, fontStyle: "italic" },
|
|
13
|
+
{ tag: tags.keyword, color: JimboColorOption.RED },
|
|
14
|
+
{ tag: tags.string, color: JimboColorOption.GOLD_TEXT },
|
|
15
|
+
{ tag: tags.number, color: JimboColorOption.BLUE },
|
|
16
|
+
{ tag: tags.bool, color: JimboColorOption.BLUE },
|
|
17
|
+
{ tag: tags.null, color: JimboColorOption.GREY },
|
|
18
|
+
{ tag: tags.propertyName, color: JimboColorOption.GREEN_TEXT },
|
|
19
|
+
{ tag: tags.typeName, color: JimboColorOption.GREEN_TEXT },
|
|
20
|
+
]);
|
|
21
|
+
const balatroTheme = EditorView.theme({
|
|
22
|
+
"&": {
|
|
23
|
+
backgroundColor: JimboColorOption.DARKEST,
|
|
24
|
+
color: JimboColorOption.WHITE,
|
|
25
|
+
fontSize: "13px",
|
|
26
|
+
height: "100%",
|
|
27
|
+
},
|
|
28
|
+
".cm-content": {
|
|
29
|
+
fontFamily: "'m6x11mono', 'm6x11plus', ui-monospace, monospace",
|
|
30
|
+
lineHeight: "22px",
|
|
31
|
+
padding: "12px 0",
|
|
32
|
+
caretColor: JimboColorOption.GOLD_TEXT,
|
|
33
|
+
minHeight: "100%",
|
|
34
|
+
},
|
|
35
|
+
".cm-gutters": {
|
|
36
|
+
backgroundColor: JimboColorOption.DARKEST,
|
|
37
|
+
color: JimboColorOption.GREY,
|
|
38
|
+
border: "none",
|
|
39
|
+
},
|
|
40
|
+
".cm-lineNumbers .cm-gutterElement": {
|
|
41
|
+
minWidth: "2ch",
|
|
42
|
+
padding: "0 6px 0 8px",
|
|
43
|
+
},
|
|
44
|
+
".cm-activeLineGutter": {
|
|
45
|
+
color: JimboColorOption.GOLD_TEXT,
|
|
46
|
+
backgroundColor: "transparent",
|
|
47
|
+
},
|
|
48
|
+
".cm-activeLine": {
|
|
49
|
+
backgroundColor: `${JimboColorOption.BLACK}20`,
|
|
50
|
+
},
|
|
51
|
+
".cm-selectionBackground": {
|
|
52
|
+
backgroundColor: `${JimboColorOption.WHITE}20 !important`,
|
|
53
|
+
},
|
|
54
|
+
"&.cm-focused .cm-selectionBackground": {
|
|
55
|
+
backgroundColor: `${JimboColorOption.WHITE}20`,
|
|
56
|
+
},
|
|
57
|
+
".cm-cursor, .cm-dropCursor": {
|
|
58
|
+
borderLeftColor: JimboColorOption.GOLD_TEXT,
|
|
59
|
+
},
|
|
60
|
+
".cm-scroller": {
|
|
61
|
+
overflow: "auto",
|
|
62
|
+
},
|
|
63
|
+
".cm-placeholder": {
|
|
64
|
+
color: JimboColorOption.GREY,
|
|
65
|
+
fontStyle: "italic",
|
|
66
|
+
},
|
|
67
|
+
}, { dark: true });
|
|
68
|
+
export function JamlCodeEditor({ value, onChange, placeholder = "", minHeight = 320, }) {
|
|
69
|
+
const containerRef = useRef(null);
|
|
70
|
+
const viewRef = useRef(null);
|
|
48
71
|
const suppressEmitRef = useRef(false);
|
|
49
|
-
// Capture initial value for the uncontrolled editor mount; subsequent
|
|
50
|
-
// updates flow through the useEffect below.
|
|
51
|
-
const initialValueRef = useRef(value);
|
|
52
|
-
// Track value across renders so we can apply only the streamed delta when
|
|
53
|
-
// the new value is a strict suffix-extension of what's already in the model.
|
|
54
72
|
const lastSyncedValueRef = useRef(value);
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
monacoRef.current = m;
|
|
58
|
-
};
|
|
73
|
+
const onChangeRef = useRef(onChange);
|
|
74
|
+
useEffect(() => { onChangeRef.current = onChange; });
|
|
59
75
|
useEffect(() => {
|
|
60
|
-
|
|
61
|
-
const m = monacoRef.current;
|
|
62
|
-
if (!editor || !m)
|
|
76
|
+
if (!containerRef.current)
|
|
63
77
|
return;
|
|
64
|
-
const
|
|
65
|
-
|
|
78
|
+
const view = new EditorView({
|
|
79
|
+
state: EditorState.create({
|
|
80
|
+
doc: lastSyncedValueRef.current,
|
|
81
|
+
extensions: [
|
|
82
|
+
history(),
|
|
83
|
+
lineNumbers(),
|
|
84
|
+
highlightActiveLine(),
|
|
85
|
+
drawSelection(),
|
|
86
|
+
yaml(),
|
|
87
|
+
syntaxHighlighting(balatroHighlight),
|
|
88
|
+
balatroTheme,
|
|
89
|
+
EditorView.lineWrapping,
|
|
90
|
+
keymap.of([indentWithTab, ...defaultKeymap, ...historyKeymap]),
|
|
91
|
+
...(placeholder ? [cmPlaceholder(placeholder)] : []),
|
|
92
|
+
EditorView.updateListener.of((update) => {
|
|
93
|
+
if (update.docChanged && !suppressEmitRef.current) {
|
|
94
|
+
onChangeRef.current(update.state.doc.toString());
|
|
95
|
+
}
|
|
96
|
+
}),
|
|
97
|
+
],
|
|
98
|
+
}),
|
|
99
|
+
parent: containerRef.current,
|
|
100
|
+
});
|
|
101
|
+
viewRef.current = view;
|
|
102
|
+
return () => {
|
|
103
|
+
view.destroy();
|
|
104
|
+
viewRef.current = null;
|
|
105
|
+
};
|
|
106
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
107
|
+
}, []);
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
const view = viewRef.current;
|
|
110
|
+
if (!view)
|
|
66
111
|
return;
|
|
67
|
-
const current =
|
|
112
|
+
const current = view.state.doc.toString();
|
|
68
113
|
if (current === value) {
|
|
69
114
|
lastSyncedValueRef.current = value;
|
|
70
115
|
return;
|
|
71
116
|
}
|
|
72
117
|
suppressEmitRef.current = true;
|
|
73
118
|
try {
|
|
74
|
-
// Streaming-friendly
|
|
75
|
-
// Monaco already has, push an insert at end-of-document. Monaco
|
|
76
|
-
// re-tokenizes only from the insertion point — no full-doc churn,
|
|
77
|
-
// no syntax-color strobe, no cursor reset.
|
|
119
|
+
// Streaming-friendly: append only the suffix when new value extends current.
|
|
78
120
|
if (value.length > current.length && value.startsWith(current)) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
model.applyEdits([
|
|
83
|
-
{
|
|
84
|
-
range: new m.Range(lastLine, lastCol, lastLine, lastCol),
|
|
85
|
-
text: suffix,
|
|
86
|
-
forceMoveMarkers: false,
|
|
87
|
-
},
|
|
88
|
-
]);
|
|
121
|
+
view.dispatch({
|
|
122
|
+
changes: { from: view.state.doc.length, insert: value.slice(current.length) },
|
|
123
|
+
});
|
|
89
124
|
}
|
|
90
125
|
else {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
range: model.getFullModelRange(),
|
|
95
|
-
text: value,
|
|
96
|
-
forceMoveMarkers: true,
|
|
97
|
-
},
|
|
98
|
-
]);
|
|
99
|
-
editor.pushUndoStop();
|
|
126
|
+
view.dispatch({
|
|
127
|
+
changes: { from: 0, to: view.state.doc.length, insert: value },
|
|
128
|
+
});
|
|
100
129
|
}
|
|
101
130
|
}
|
|
102
131
|
finally {
|
|
@@ -104,35 +133,5 @@ export function JamlCodeEditor({ value, onChange, minHeight = 320, }) {
|
|
|
104
133
|
lastSyncedValueRef.current = value;
|
|
105
134
|
}
|
|
106
135
|
}, [value]);
|
|
107
|
-
return (
|
|
108
|
-
.monaco-editor .iPadShowKeyboard,
|
|
109
|
-
.monaco-editor [class*="iPadShowKeyboard"] { display: none !important; }
|
|
110
|
-
` }), _jsx(Editor, { height: `${minHeight}px`, defaultLanguage: "yaml", defaultValue: initialValueRef.current, theme: "jaml-balatro-dark", onChange: (next) => {
|
|
111
|
-
if (suppressEmitRef.current)
|
|
112
|
-
return;
|
|
113
|
-
onChange(next ?? "");
|
|
114
|
-
}, onMount: handleMount, beforeMount: defineBalatroTheme, options: {
|
|
115
|
-
minimap: { enabled: false },
|
|
116
|
-
scrollBeyondLastLine: false,
|
|
117
|
-
fontSize: 13,
|
|
118
|
-
lineHeight: 22,
|
|
119
|
-
fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
|
|
120
|
-
lineNumbers: "on",
|
|
121
|
-
lineNumbersMinChars: 2,
|
|
122
|
-
lineDecorationsWidth: 4,
|
|
123
|
-
glyphMargin: false,
|
|
124
|
-
folding: false,
|
|
125
|
-
automaticLayout: true,
|
|
126
|
-
padding: { top: 12, bottom: 12 },
|
|
127
|
-
wordWrap: "on",
|
|
128
|
-
formatOnPaste: true,
|
|
129
|
-
formatOnType: true,
|
|
130
|
-
renderLineHighlight: "line",
|
|
131
|
-
scrollbar: { verticalScrollbarSize: 8, horizontalScrollbarSize: 8 },
|
|
132
|
-
// Mobile/chat-WebView UX: kill the context menu ("Change All Occurrences" etc. covering half
|
|
133
|
-
// the file on long-press) and the accessibility-help keyboard widget that's just clutter when
|
|
134
|
-
// the OS keyboard is already open.
|
|
135
|
-
contextmenu: false,
|
|
136
|
-
accessibilitySupport: "off",
|
|
137
|
-
} })] }));
|
|
136
|
+
return (_jsx("div", { ref: containerRef, style: { width: "100%", minHeight, background: JimboColorOption.DARKEST } }));
|
|
138
137
|
}
|