@tooee/renderers 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CodeView.d.ts +5 -1
- package/dist/CodeView.d.ts.map +1 -1
- package/dist/CodeView.js +28 -61
- package/dist/CodeView.js.map +1 -1
- package/dist/MarkdownView.d.ts +6 -2
- package/dist/MarkdownView.d.ts.map +1 -1
- package/dist/MarkdownView.js +29 -24
- package/dist/MarkdownView.js.map +1 -1
- package/dist/RowDocumentRenderable.d.ts +87 -0
- package/dist/RowDocumentRenderable.d.ts.map +1 -0
- package/dist/RowDocumentRenderable.js +428 -0
- package/dist/RowDocumentRenderable.js.map +1 -0
- package/dist/Table.d.ts +5 -1
- package/dist/Table.d.ts.map +1 -1
- package/dist/Table.js +24 -31
- package/dist/Table.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/row-document.d.ts +7 -0
- package/dist/row-document.d.ts.map +1 -0
- package/dist/row-document.js +4 -0
- package/dist/row-document.js.map +1 -0
- package/package.json +2 -2
- package/src/CodeView.tsx +39 -81
- package/src/MarkdownView.tsx +46 -51
- package/src/RowDocumentRenderable.ts +607 -0
- package/src/Table.tsx +37 -35
- package/src/index.ts +6 -0
- package/src/row-document.ts +10 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"row-document.d.ts","sourceRoot":"","sources":["../src/row-document.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAIlE,OAAO,QAAQ,gBAAgB,CAAC;IAC9B,UAAU,iBAAiB;QACzB,cAAc,EAAE,OAAO,qBAAqB,CAAA;KAC7C;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"row-document.js","sourceRoot":"","sources":["../src/row-document.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAElE,MAAM,CAAC,EAAE,cAAc,EAAE,qBAAqB,EAAE,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tooee/renderers",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Content renderers (markdown, code, image, table) for Tooee",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Gareth Andrew",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"typecheck": "tsc --noEmit"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@tooee/themes": "0.1.
|
|
40
|
+
"@tooee/themes": "0.1.6",
|
|
41
41
|
"marked": "^16.3.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
package/src/CodeView.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { useEffect, useRef } from "react"
|
|
2
|
-
import type { LineNumberRenderable } from "@opentui/core"
|
|
1
|
+
import { useEffect, useRef, type RefObject } from "react"
|
|
3
2
|
import { useTheme } from "@tooee/themes"
|
|
3
|
+
import type { RowDocumentRenderable, RowDocumentPalette, RowDocumentDecorations } from "./RowDocumentRenderable.js"
|
|
4
|
+
import "./row-document.js"
|
|
4
5
|
|
|
5
6
|
interface CodeViewProps {
|
|
6
7
|
content: string
|
|
@@ -12,6 +13,7 @@ interface CodeViewProps {
|
|
|
12
13
|
matchingLines?: Set<number>
|
|
13
14
|
currentMatchLine?: number
|
|
14
15
|
toggledLines?: Set<number>
|
|
16
|
+
docRef?: RefObject<RowDocumentRenderable | null>
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
export function CodeView({
|
|
@@ -24,94 +26,50 @@ export function CodeView({
|
|
|
24
26
|
matchingLines,
|
|
25
27
|
currentMatchLine,
|
|
26
28
|
toggledLines,
|
|
29
|
+
docRef,
|
|
27
30
|
}: CodeViewProps) {
|
|
28
31
|
const { syntax, theme } = useTheme()
|
|
29
|
-
const
|
|
32
|
+
const internalRef = useRef<RowDocumentRenderable>(null)
|
|
33
|
+
const effectiveRef = docRef ?? internalRef
|
|
30
34
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
const palette: RowDocumentPalette = {
|
|
36
|
+
gutterFg: theme.textMuted,
|
|
37
|
+
gutterBg: theme.backgroundElement,
|
|
38
|
+
cursorBg: theme.cursorLine,
|
|
39
|
+
selectionBg: theme.selection,
|
|
40
|
+
matchBg: theme.warning,
|
|
41
|
+
currentMatchBg: theme.primary,
|
|
42
|
+
toggledBg: theme.backgroundPanel,
|
|
43
|
+
cursorSignFg: theme.primary,
|
|
44
|
+
matchSignFg: theme.warning,
|
|
45
|
+
currentMatchSignFg: theme.primary,
|
|
46
|
+
}
|
|
37
47
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
// Selection range
|
|
49
|
-
if (selectionStart != null && selectionEnd != null) {
|
|
50
|
-
for (let i = selectionStart; i <= selectionEnd; i++) {
|
|
51
|
-
ref.setLineColor(i, { content: theme.selection, gutter: theme.selection })
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (toggledLines) {
|
|
56
|
-
for (const line of toggledLines) {
|
|
57
|
-
const isSelected =
|
|
58
|
-
selectionStart != null && selectionEnd != null && line >= selectionStart && line <= selectionEnd
|
|
59
|
-
if (line === cursor || isSelected) continue
|
|
60
|
-
ref.setLineColor(line, {
|
|
61
|
-
content: theme.backgroundPanel,
|
|
62
|
-
gutter: theme.backgroundPanel,
|
|
63
|
-
})
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Cursor line (overwrites selection color on cursor line)
|
|
68
|
-
if (cursor != null) {
|
|
69
|
-
ref.setLineColor(cursor, { content: theme.cursorLine, gutter: theme.cursorLine })
|
|
70
|
-
ref.setLineSign(cursor, {
|
|
71
|
-
before: "▸",
|
|
72
|
-
beforeColor: theme.primary,
|
|
73
|
-
// Preserve search match sign if present
|
|
74
|
-
...(matchingLines?.has(cursor)
|
|
75
|
-
? {
|
|
76
|
-
after: "●",
|
|
77
|
-
afterColor: cursor === currentMatchLine ? theme.primary : theme.warning,
|
|
78
|
-
}
|
|
79
|
-
: {}),
|
|
80
|
-
})
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
const decorations: RowDocumentDecorations = {
|
|
50
|
+
cursorRow: cursor,
|
|
51
|
+
selection: selectionStart != null && selectionEnd != null
|
|
52
|
+
? { start: selectionStart, end: selectionEnd }
|
|
53
|
+
: null,
|
|
54
|
+
matchingRows: matchingLines,
|
|
55
|
+
currentMatchRow: currentMatchLine,
|
|
56
|
+
toggledRows: toggledLines,
|
|
81
57
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
cursor,
|
|
85
|
-
selectionStart,
|
|
86
|
-
selectionEnd,
|
|
87
|
-
matchingLines,
|
|
88
|
-
currentMatchLine,
|
|
89
|
-
toggledLines,
|
|
90
|
-
theme,
|
|
91
|
-
])
|
|
58
|
+
effectiveRef.current?.setDecorations(decorations)
|
|
59
|
+
}, [cursor, selectionStart, selectionEnd, matchingLines, currentMatchLine, toggledLines])
|
|
92
60
|
|
|
93
61
|
const codeElement = <code content={content} filetype={language} syntaxStyle={syntax} />
|
|
94
62
|
|
|
95
63
|
return (
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
64
|
+
<row-document
|
|
65
|
+
ref={effectiveRef}
|
|
66
|
+
key={theme.textMuted + theme.backgroundElement}
|
|
67
|
+
showLineNumbers={showLineNumbers}
|
|
68
|
+
palette={palette}
|
|
69
|
+
signColumnWidth={1}
|
|
70
|
+
style={{ flexGrow: 1 }}
|
|
100
71
|
>
|
|
101
|
-
{
|
|
102
|
-
|
|
103
|
-
ref={lineNumRef}
|
|
104
|
-
key={theme.textMuted + theme.backgroundElement}
|
|
105
|
-
fg={theme.textMuted}
|
|
106
|
-
bg={theme.backgroundElement}
|
|
107
|
-
paddingRight={1}
|
|
108
|
-
showLineNumbers
|
|
109
|
-
>
|
|
110
|
-
{codeElement}
|
|
111
|
-
</line-number>
|
|
112
|
-
) : (
|
|
113
|
-
codeElement
|
|
114
|
-
)}
|
|
115
|
-
</box>
|
|
72
|
+
{codeElement}
|
|
73
|
+
</row-document>
|
|
116
74
|
)
|
|
117
75
|
}
|
package/src/MarkdownView.tsx
CHANGED
|
@@ -1,83 +1,78 @@
|
|
|
1
1
|
import { marked, type Token, type Tokens } from "marked"
|
|
2
|
-
import type
|
|
2
|
+
import { useEffect, useRef, type ReactNode, type RefObject } from "react"
|
|
3
3
|
import { useTheme, type ResolvedTheme } from "@tooee/themes"
|
|
4
4
|
import type { SyntaxStyle } from "@opentui/core"
|
|
5
5
|
import { Table } from "./Table.js"
|
|
6
|
+
import type { RowDocumentRenderable, RowDocumentPalette, RowDocumentDecorations } from "./RowDocumentRenderable.js"
|
|
7
|
+
import "./row-document.js"
|
|
6
8
|
|
|
7
9
|
interface MarkdownViewProps {
|
|
8
10
|
content: string
|
|
11
|
+
showLineNumbers?: boolean
|
|
9
12
|
activeBlock?: number
|
|
10
13
|
selectedBlocks?: { start: number; end: number }
|
|
11
14
|
matchingBlocks?: Set<number>
|
|
12
15
|
currentMatchBlock?: number
|
|
13
16
|
toggledBlocks?: Set<number>
|
|
17
|
+
docRef?: RefObject<RowDocumentRenderable | null>
|
|
14
18
|
}
|
|
15
19
|
|
|
16
20
|
export function MarkdownView({
|
|
17
21
|
content,
|
|
22
|
+
showLineNumbers = true,
|
|
18
23
|
activeBlock,
|
|
19
24
|
selectedBlocks,
|
|
20
25
|
matchingBlocks,
|
|
21
26
|
currentMatchBlock,
|
|
22
27
|
toggledBlocks,
|
|
28
|
+
docRef,
|
|
23
29
|
}: MarkdownViewProps) {
|
|
24
30
|
const { theme, syntax } = useTheme()
|
|
31
|
+
const internalRef = useRef<RowDocumentRenderable>(null)
|
|
32
|
+
const effectiveRef = docRef ?? internalRef
|
|
25
33
|
const tokens = marked.lexer(content)
|
|
26
34
|
const blocks = tokens.filter((t) => t.type !== "space")
|
|
27
35
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const blockContent = (
|
|
41
|
-
<TokenRenderer key={index} token={token} theme={theme} syntax={syntax} />
|
|
42
|
-
)
|
|
36
|
+
const palette: RowDocumentPalette = {
|
|
37
|
+
gutterFg: theme.textMuted,
|
|
38
|
+
gutterBg: theme.backgroundElement,
|
|
39
|
+
cursorBg: theme.cursorLine,
|
|
40
|
+
selectionBg: theme.selection,
|
|
41
|
+
matchBg: theme.warning,
|
|
42
|
+
currentMatchBg: theme.primary,
|
|
43
|
+
toggledBg: theme.backgroundPanel,
|
|
44
|
+
cursorSignFg: theme.primary,
|
|
45
|
+
matchSignFg: theme.warning,
|
|
46
|
+
currentMatchSignFg: theme.primary,
|
|
47
|
+
}
|
|
43
48
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
)
|
|
55
|
-
}
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
const decorations: RowDocumentDecorations = {
|
|
51
|
+
cursorRow: activeBlock,
|
|
52
|
+
selection: selectedBlocks ? { start: selectedBlocks.start, end: selectedBlocks.end } : null,
|
|
53
|
+
matchingRows: matchingBlocks,
|
|
54
|
+
currentMatchRow: currentMatchBlock,
|
|
55
|
+
toggledRows: toggledBlocks,
|
|
56
|
+
}
|
|
57
|
+
effectiveRef.current?.setDecorations(decorations)
|
|
58
|
+
}, [activeBlock, selectedBlocks, matchingBlocks, currentMatchBlock, toggledBlocks])
|
|
56
59
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
)
|
|
61
|
-
}
|
|
60
|
+
const blockElements = blocks.map((token, index) => (
|
|
61
|
+
<TokenRenderer key={index} token={token} theme={theme} syntax={syntax} />
|
|
62
|
+
))
|
|
62
63
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if (currentMatchBlock === index) return { accent: theme.accent, background: null }
|
|
76
|
-
if (matchingBlocks?.has(index)) return { accent: theme.warning, background: null }
|
|
77
|
-
if (selectedBlocks && index >= selectedBlocks.start && index <= selectedBlocks.end) {
|
|
78
|
-
return { accent: theme.secondary, background: theme.backgroundPanel }
|
|
79
|
-
}
|
|
80
|
-
return { accent: null, background: null }
|
|
64
|
+
return (
|
|
65
|
+
<row-document
|
|
66
|
+
ref={effectiveRef}
|
|
67
|
+
key={theme.textMuted + theme.backgroundElement}
|
|
68
|
+
showLineNumbers={showLineNumbers}
|
|
69
|
+
palette={palette}
|
|
70
|
+
signColumnWidth={1}
|
|
71
|
+
style={{ flexGrow: 1 }}
|
|
72
|
+
>
|
|
73
|
+
{blockElements}
|
|
74
|
+
</row-document>
|
|
75
|
+
)
|
|
81
76
|
}
|
|
82
77
|
|
|
83
78
|
function TokenRenderer({
|