Skip to content

Commit 2d3bf5e

Browse files
committed
feat: finish table impl
1 parent 9ebc5f4 commit 2d3bf5e

File tree

1 file changed

+88
-53
lines changed

1 file changed

+88
-53
lines changed

package/src/components/Message/MessageSimple/utils/renderText.tsx

Lines changed: 88 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { PropsWithChildren, ReactNode, useCallback, useRef, useState } from 'react';
1+
import React, { PropsWithChildren, ReactNode, useCallback, useMemo, useRef, useState } from 'react';
22
import {
33
GestureResponderEvent,
44
Linking,
@@ -41,17 +41,14 @@ const ReactiveScrollView = ({ children }: { children: ReactNode }) => {
4141
const [scrollViewXOffset, setScrollViewXOffset] = useState(0);
4242
const scrollViewRef = useRef<ScrollView>(null);
4343

44-
const scrollTo = useCallback(
45-
(translation: number) => {
46-
if (scrollViewRef.current) {
47-
scrollViewRef.current.scrollTo({
48-
animated: false,
49-
x: translation,
50-
});
51-
}
52-
},
53-
[scrollViewRef],
54-
);
44+
const scrollTo = useCallback((translation: number) => {
45+
if (scrollViewRef.current) {
46+
scrollViewRef.current.scrollTo({
47+
animated: false,
48+
x: translation,
49+
});
50+
}
51+
}, []);
5552

5653
const panGesture = Gesture.Pan()
5754
.activeOffsetX([-10, 10])
@@ -73,6 +70,7 @@ const ReactiveScrollView = ({ children }: { children: ReactNode }) => {
7370
horizontal
7471
nestedScrollEnabled={true}
7572
ref={scrollViewRef}
73+
scrollEnabled={false}
7674
>
7775
{children}
7876
</ScrollView>
@@ -126,7 +124,7 @@ const defaultMarkdownStyles: MarkdownStyle = {
126124
},
127125
tableHeader: {
128126
backgroundColor: '#222222',
129-
flexDirection: 'row',
127+
flex: 1,
130128
justifyContent: 'space-around',
131129
},
132130
tableHeaderCell: {
@@ -221,6 +219,7 @@ export const renderText = <
221219
borderRadius: 3,
222220
borderWidth: 1,
223221
flex: 1,
222+
flexDirection: 'row',
224223
},
225224
tableHeader: {
226225
backgroundColor: '#222222',
@@ -233,8 +232,8 @@ export const renderText = <
233232
padding: 5,
234233
},
235234
tableRow: {
235+
alignItems: 'center',
236236
borderColor: '#222222',
237-
flexDirection: 'row',
238237
justifyContent: 'space-around',
239238
},
240239
tableRowCell: {
@@ -382,49 +381,17 @@ export const renderText = <
382381
/>
383382
);
384383

385-
const CodeBlockReact: ReactNodeOutput = (node, _, state) => (
384+
const codeBlockReact: ReactNodeOutput = (node, _, state) => (
386385
<ReactiveScrollView key={state.key}>
387386
<Text style={styles.codeBlock}>{node.content}</Text>
388387
</ReactiveScrollView>
389388
);
390389

391-
const tableReact: ReactNodeOutput = (node, output, state) => {
392-
const headers = node?.header?.map((content: SingleASTNode, idx: number) => (
393-
<Text key={idx} style={styles.tableHeaderCell}>
394-
{output(content, state)}
395-
</Text>
396-
));
397-
398-
const header = (
399-
<View key={-1} style={styles.tableHeader}>
400-
{headers}
401-
</View>
402-
);
403-
404-
const rows = node?.cells?.map((row: SingleASTNode, r: number) => {
405-
const cells = row.map((content: SingleASTNode, c: number) => (
406-
<View key={c} style={styles.tableRowCell}>
407-
{output(content, state)}
408-
</View>
409-
));
410-
const rowStyles = [styles.tableRow];
411-
if (node.cells.length - 1 === r) {
412-
rowStyles.push(styles.tableRowLast);
413-
}
414-
415-
return (
416-
<View key={r} style={rowStyles}>
417-
{cells}
418-
</View>
419-
);
420-
});
421-
422-
return (
423-
<ReactiveScrollView key={state.key}>
424-
<View style={styles.table}>{[header, rows]}</View>
425-
</ReactiveScrollView>
426-
);
427-
};
390+
const tableReact: ReactNodeOutput = (node, output, state) => (
391+
<ReactiveScrollView key={state.key}>
392+
<MarkdownTable node={node} output={output} state={state} styles={styles} />
393+
</ReactiveScrollView>
394+
);
428395

429396
const customRules = {
430397
// do not render images, we will scrape them out of the message and show on attachment card component
@@ -446,7 +413,7 @@ export const renderText = <
446413
},
447414
}
448415
: {}),
449-
codeBlock: { react: CodeBlockReact },
416+
codeBlock: { react: codeBlockReact },
450417
table: { react: tableReact },
451418
};
452419

@@ -538,3 +505,71 @@ const ListRow = ({ children, style }: PropsWithChildren<ViewProps>) => (
538505
const ListItem = ({ children, style }: PropsWithChildren<TextProps>) => (
539506
<Text style={style}>{children}</Text>
540507
);
508+
509+
export type MarkdownTableProps = {
510+
node: SingleASTNode;
511+
output: ReactOutput;
512+
state: State;
513+
styles: Partial<MarkdownStyle>;
514+
};
515+
516+
const transpose = (matrix: SingleASTNode[][]) =>
517+
matrix[0].map((_, colIndex) => matrix.map((row) => row[colIndex]));
518+
519+
const MarkdownTable = ({ node, output, state, styles }: MarkdownTableProps) => {
520+
const content = useMemo(() => {
521+
const nodeContent = [node?.header, ...node?.cells];
522+
return transpose(nodeContent);
523+
}, [node?.cells, node?.header]);
524+
const columns = content?.map((column, idx) => (
525+
<MarkdownTableColumn
526+
items={column}
527+
key={`column-${idx}`}
528+
output={output}
529+
state={state}
530+
styles={styles}
531+
/>
532+
));
533+
534+
return (
535+
<View key={state.key} style={styles.table}>
536+
{columns}
537+
</View>
538+
);
539+
};
540+
541+
export type MarkdownTableRowProps = {
542+
items: SingleASTNode[];
543+
output: ReactOutput;
544+
state: State;
545+
styles: Partial<MarkdownStyle>;
546+
};
547+
548+
const MarkdownTableColumn = ({ items, output, state, styles }: MarkdownTableRowProps) => {
549+
const [headerCellContent, ...columnCellContents] = items;
550+
551+
const ColumnCell = useCallback(
552+
({ content }: { content: SingleASTNode }) =>
553+
// console.log('CONTENT: ', content);
554+
content ? (
555+
<View style={styles.tableRow}>
556+
<View style={styles.tableRowCell}>{output(content, state)}</View>
557+
</View>
558+
) : null,
559+
[output, state, styles],
560+
);
561+
562+
return (
563+
<View style={{ flexDirection: 'column', flex: 1 }}>
564+
{headerCellContent ? (
565+
<View key={-1} style={styles.tableHeader}>
566+
<Text style={styles.tableHeaderCell}>{output(headerCellContent, state)}</Text>
567+
</View>
568+
) : null}
569+
{columnCellContents &&
570+
columnCellContents.map((content, idx) => (
571+
<ColumnCell content={content} key={`cell-${idx}`} />
572+
))}
573+
</View>
574+
);
575+
};

0 commit comments

Comments
 (0)