@amritanshu3011/mdx-renderer 1.0.4 → 1.0.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/MDXRenderer.js +26 -3
- package/dist/components/smart/FlowBlock.d.ts +11 -4
- package/dist/components/smart/FlowBlock.js +79 -104
- package/dist/components/smart/InteractiveCompositeBlock.js +135 -17
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/theme/themes.js +2 -2
- package/package.json +9 -6
package/dist/MDXRenderer.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { MDXProvider } from '@mdx-js/react';
|
|
3
|
-
|
|
3
|
+
// 👇 CHANGE 1: Use the Context Hook (so updates happen live)
|
|
4
|
+
// import { useThemeWithFallback } from './utils/useThemeWithFallback';
|
|
5
|
+
import { useTheme } from './theme/ThemeContext';
|
|
4
6
|
// Text components
|
|
5
7
|
import { Heading } from './components/text/Heading';
|
|
6
8
|
import { Paragraph } from './components/text/Paragraph';
|
|
@@ -51,6 +53,27 @@ const components = {
|
|
|
51
53
|
ComparisonGrid,
|
|
52
54
|
};
|
|
53
55
|
export const MDXRenderer = ({ children, className = 'mdx-content' }) => {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
// 👇 CHANGE 3: Get theme from Context
|
|
57
|
+
const { theme } = useTheme();
|
|
58
|
+
// 👇 CHANGE 4: Create the Bridge (JS -> CSS Variables)
|
|
59
|
+
const themeStyles = {
|
|
60
|
+
// Colors
|
|
61
|
+
'--color-primary': theme.colors.primary,
|
|
62
|
+
'--color-secondary': theme.colors.secondary,
|
|
63
|
+
'--color-text': theme.colors.text,
|
|
64
|
+
'--color-text-secondary': theme.colors.textSecondary,
|
|
65
|
+
'--color-background': theme.colors.background,
|
|
66
|
+
'--color-card-bg': theme.colors.cardBackground,
|
|
67
|
+
'--color-border': theme.colors.border,
|
|
68
|
+
// Spacing
|
|
69
|
+
'--spacing-small': theme.spacing.small,
|
|
70
|
+
'--spacing-medium': theme.spacing.medium,
|
|
71
|
+
'--spacing-large': theme.spacing.large,
|
|
72
|
+
// Typography
|
|
73
|
+
'--font-family': theme.typography.fontFamily,
|
|
74
|
+
// Border Radius
|
|
75
|
+
'--radius-small': theme.borderRadius.small,
|
|
76
|
+
'--radius-medium': theme.borderRadius.medium,
|
|
77
|
+
};
|
|
78
|
+
return (_jsx("div", { className: className, style: themeStyles, children: _jsx(MDXProvider, { components: components, children: children }) }));
|
|
56
79
|
};
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
interface FlowStep {
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
export interface FlowStep {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
value: number;
|
|
6
|
+
color?: string;
|
|
7
|
+
dropOff?: string;
|
|
8
|
+
breakdown?: {
|
|
9
|
+
label: string;
|
|
10
|
+
value: number;
|
|
11
|
+
}[];
|
|
5
12
|
}
|
|
6
13
|
export interface FlowBlockProps {
|
|
7
14
|
title: string;
|
|
15
|
+
total_candidates?: number;
|
|
8
16
|
steps: FlowStep[];
|
|
9
17
|
}
|
|
10
18
|
export declare const FlowBlock: React.FC<FlowBlockProps>;
|
|
11
|
-
export {};
|
|
@@ -1,46 +1,16 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
2
|
-
import React, { useState
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
3
|
import { useThemeWithFallback } from '../../utils/useThemeWithFallback';
|
|
4
|
-
export const FlowBlock = ({ title, steps }) => {
|
|
4
|
+
export const FlowBlock = ({ title, total_candidates, steps }) => {
|
|
5
5
|
const theme = useThemeWithFallback();
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const [
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
let data = [...steps];
|
|
15
|
-
// 1. Filter
|
|
16
|
-
if (filterText) {
|
|
17
|
-
const lower = filterText.toLowerCase();
|
|
18
|
-
data = data.filter(s => s.title.toLowerCase().includes(lower) ||
|
|
19
|
-
s.description.toLowerCase().includes(lower));
|
|
20
|
-
}
|
|
21
|
-
// 2. Sort
|
|
22
|
-
if (sortMode !== 'original') {
|
|
23
|
-
data.sort((a, b) => {
|
|
24
|
-
return sortMode === 'asc'
|
|
25
|
-
? a.title.localeCompare(b.title)
|
|
26
|
-
: b.title.localeCompare(a.title);
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
return data;
|
|
30
|
-
}, [steps, filterText, sortMode]);
|
|
31
|
-
// --- Logic: Grouping ---
|
|
32
|
-
const groupedData = useMemo(() => {
|
|
33
|
-
if (!isGrouped)
|
|
34
|
-
return { 'All Steps': processedData };
|
|
35
|
-
return processedData.reduce((acc, step) => {
|
|
36
|
-
const key = step.title.charAt(0).toUpperCase();
|
|
37
|
-
if (!acc[key])
|
|
38
|
-
acc[key] = [];
|
|
39
|
-
acc[key].push(step);
|
|
40
|
-
return acc;
|
|
41
|
-
}, {});
|
|
42
|
-
}, [processedData, isGrouped]);
|
|
43
|
-
// --- Styles Helper ---
|
|
6
|
+
const [viewMode, setViewMode] = useState('chart');
|
|
7
|
+
// Track expanded rows for both Chart and Table views
|
|
8
|
+
const [expandedSteps, setExpandedSteps] = useState({});
|
|
9
|
+
const toggleStep = (id) => {
|
|
10
|
+
setExpandedSteps(prev => ({ ...prev, [id]: !prev[id] }));
|
|
11
|
+
};
|
|
12
|
+
const maxValue = Math.max(...steps.map(s => s.value));
|
|
13
|
+
// --- Styles ---
|
|
44
14
|
const btnStyle = (active) => ({
|
|
45
15
|
padding: `${theme.spacing.small} ${theme.spacing.medium}`,
|
|
46
16
|
backgroundColor: active ? theme.colors.primary : 'transparent',
|
|
@@ -49,74 +19,79 @@ export const FlowBlock = ({ title, steps }) => {
|
|
|
49
19
|
borderRadius: theme.borderRadius.small,
|
|
50
20
|
cursor: 'pointer',
|
|
51
21
|
fontSize: theme.typography.smallSize,
|
|
52
|
-
fontWeight: 'bold'
|
|
22
|
+
fontWeight: 'bold',
|
|
23
|
+
transition: 'all 0.2s',
|
|
53
24
|
});
|
|
54
25
|
return (_jsxs("div", { style: {
|
|
55
26
|
margin: `${theme.spacing.large} 0`,
|
|
56
|
-
border: `1px solid ${theme.colors.border || '#
|
|
27
|
+
border: `1px solid ${theme.colors.border || '#e5e7eb'}`,
|
|
57
28
|
borderRadius: theme.borderRadius.medium,
|
|
29
|
+
backgroundColor: theme.colors.background,
|
|
58
30
|
boxShadow: '0 4px 12px rgba(0,0,0,0.05)',
|
|
59
31
|
overflow: 'hidden'
|
|
60
32
|
}, children: [_jsxs("div", { style: {
|
|
61
|
-
padding:
|
|
62
|
-
borderBottom: `1px solid ${theme.colors.border || '#
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
33
|
+
padding: '16px 20px',
|
|
34
|
+
borderBottom: `1px solid ${theme.colors.border || '#e5e7eb'}`,
|
|
35
|
+
display: 'flex',
|
|
36
|
+
justifyContent: 'space-between',
|
|
37
|
+
alignItems: 'center',
|
|
38
|
+
backgroundColor: theme.colors.cardBackground
|
|
39
|
+
}, children: [_jsxs("div", { children: [_jsx("h3", { style: { margin: 0, fontSize: '18px', color: theme.colors.text }, children: title }), total_candidates && (_jsxs("div", { style: { fontSize: '13px', color: theme.colors.textSecondary, marginTop: '4px' }, children: ["Total Volume: ", _jsx("strong", { children: total_candidates.toLocaleString() })] }))] }), _jsxs("div", { style: { display: 'flex', borderRadius: '6px', overflow: 'hidden', border: `1px solid ${theme.colors.primary}` }, children: [_jsx("button", { onClick: () => setViewMode('chart'), style: { ...btnStyle(viewMode === 'chart'), border: 'none', borderRadius: 0 }, children: "Funnel" }), _jsx("button", { onClick: () => setViewMode('table'), style: { ...btnStyle(viewMode === 'table'), border: 'none', borderRadius: 0 }, children: "Grid" })] })] }), _jsxs("div", { style: { padding: '24px' }, children: [viewMode === 'chart' && (_jsx("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '8px' }, children: steps.map((step, index) => {
|
|
40
|
+
const widthPercentage = Math.max(25, (step.value / maxValue) * 100);
|
|
41
|
+
const isExpanded = expandedSteps[step.id];
|
|
42
|
+
const hasBreakdown = step.breakdown && step.breakdown.length > 0;
|
|
43
|
+
return (_jsxs("div", { style: { width: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center' }, children: [_jsxs("div", { onClick: () => hasBreakdown && toggleStep(step.id), style: {
|
|
44
|
+
width: `${widthPercentage}%`,
|
|
45
|
+
backgroundColor: step.color || theme.colors.primary,
|
|
46
|
+
borderRadius: '8px',
|
|
47
|
+
padding: '12px 16px',
|
|
48
|
+
color: '#fff',
|
|
49
|
+
display: 'flex',
|
|
50
|
+
justifyContent: 'space-between',
|
|
51
|
+
alignItems: 'center',
|
|
52
|
+
cursor: hasBreakdown ? 'pointer' : 'default',
|
|
53
|
+
boxShadow: '0 2px 4px rgba(0,0,0,0.15)',
|
|
54
|
+
transition: 'width 0.3s ease, transform 0.1s',
|
|
55
|
+
position: 'relative'
|
|
56
|
+
}, onMouseEnter: (e) => e.currentTarget.style.transform = hasBreakdown ? 'scale(1.01)' : 'none', onMouseLeave: (e) => e.currentTarget.style.transform = 'none', children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '8px' }, children: [hasBreakdown && _jsx("span", { style: { fontSize: '10px' }, children: isExpanded ? '▼' : '▶' }), _jsxs("span", { style: { fontWeight: 600, fontSize: '15px' }, children: [index + 1, ". ", step.label] })] }), _jsx("span", { style: { fontWeight: 'bold', backgroundColor: 'rgba(255,255,255,0.2)', padding: '2px 8px', borderRadius: '4px' }, children: step.value.toLocaleString() })] }), isExpanded && hasBreakdown && (_jsx("div", { style: {
|
|
57
|
+
width: `${widthPercentage}%`,
|
|
58
|
+
backgroundColor: theme.colors.cardBackground,
|
|
59
|
+
border: `1px solid ${theme.colors.border}`,
|
|
60
|
+
borderTop: 'none',
|
|
61
|
+
borderRadius: '0 0 8px 8px',
|
|
62
|
+
padding: '12px',
|
|
63
|
+
marginBottom: '10px',
|
|
64
|
+
boxShadow: 'inset 0 4px 6px -4px rgba(0,0,0,0.1)'
|
|
65
|
+
}, children: _jsx("table", { style: { width: '100%', fontSize: '13px', color: theme.colors.text }, children: _jsx("tbody", { children: step.breakdown.map((item, idx) => (_jsxs("tr", { style: { borderBottom: idx !== step.breakdown.length - 1 ? `1px solid ${theme.colors.border}` : 'none' }, children: [_jsx("td", { style: { padding: '6px 0', color: theme.colors.textSecondary }, children: item.label }), _jsx("td", { style: { padding: '6px 0', textAlign: 'right', fontWeight: 'bold' }, children: item.value.toLocaleString() })] }, idx))) }) }) })), !isExpanded && index < steps.length - 1 && (_jsxs("div", { style: { height: '24px', display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative', width: '100%' }, children: [_jsx("div", { style: { width: '2px', height: '100%', backgroundColor: theme.colors.border } }), step.dropOff && (_jsxs("span", { style: {
|
|
66
|
+
position: 'absolute',
|
|
67
|
+
fontSize: '11px',
|
|
68
|
+
color: '#dc2626',
|
|
69
|
+
backgroundColor: '#fef2f2',
|
|
70
|
+
padding: '2px 8px',
|
|
71
|
+
borderRadius: '10px',
|
|
72
|
+
border: '1px solid #fecaca',
|
|
73
|
+
fontWeight: 600
|
|
74
|
+
}, children: [step.dropOff, " Drop-off"] }))] }))] }, step.id));
|
|
75
|
+
}) })), viewMode === 'table' && (_jsx("div", { style: { overflowX: 'auto', border: `1px solid ${theme.colors.border}`, borderRadius: '8px' }, children: _jsxs("table", { style: { width: '100%', borderCollapse: 'collapse', fontSize: '14px', backgroundColor: theme.colors.cardBackground }, children: [_jsx("thead", { children: _jsxs("tr", { style: { backgroundColor: theme.colors.background, borderBottom: `2px solid ${theme.colors.border}` }, children: [_jsx("th", { style: { padding: '12px 16px', textAlign: 'left', color: theme.colors.textSecondary, fontWeight: 600 }, children: "Stage" }), _jsx("th", { style: { padding: '12px 16px', textAlign: 'right', color: theme.colors.textSecondary, fontWeight: 600 }, children: "Candidates" }), _jsx("th", { style: { padding: '12px 16px', textAlign: 'right', color: theme.colors.textSecondary, fontWeight: 600 }, children: "Status" })] }) }), _jsx("tbody", { children: steps.map((step, i) => {
|
|
76
|
+
const hasBreakdown = step.breakdown && step.breakdown.length > 0;
|
|
77
|
+
const isExpanded = expandedSteps[step.id];
|
|
78
|
+
return (_jsxs(React.Fragment, { children: [_jsxs("tr", { onClick: () => hasBreakdown && toggleStep(step.id), style: {
|
|
79
|
+
borderBottom: isExpanded ? 'none' : `1px solid ${theme.colors.border}`,
|
|
80
|
+
cursor: hasBreakdown ? 'pointer' : 'default',
|
|
81
|
+
transition: 'background-color 0.2s'
|
|
82
|
+
}, onMouseEnter: (e) => e.currentTarget.style.backgroundColor = theme.colors.background, onMouseLeave: (e) => e.currentTarget.style.backgroundColor = 'transparent', children: [_jsx("td", { style: { padding: '14px 16px', fontWeight: 600, color: theme.colors.text }, children: _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '8px' }, children: [hasBreakdown && (_jsx("span", { style: { color: theme.colors.primary, fontSize: '12px' }, children: isExpanded ? '▼' : '▶' })), i + 1, ". ", step.label] }) }), _jsx("td", { style: { padding: '14px 16px', textAlign: 'right', fontWeight: 'bold', fontSize: '15px' }, children: step.value.toLocaleString() }), _jsx("td", { style: { padding: '14px 16px', textAlign: 'right' }, children: step.dropOff ? (_jsxs("span", { style: {
|
|
83
|
+
color: '#dc2626',
|
|
84
|
+
backgroundColor: '#fef2f2',
|
|
85
|
+
padding: '4px 8px',
|
|
86
|
+
borderRadius: '4px',
|
|
87
|
+
fontSize: '12px',
|
|
88
|
+
fontWeight: 600
|
|
89
|
+
}, children: [step.dropOff, " Loss"] })) : (_jsx("span", { style: { color: '#16a34a', fontSize: '20px' }, children: "\u2022" })) })] }), isExpanded && hasBreakdown && (_jsx("tr", { style: { borderBottom: `1px solid ${theme.colors.border}`, backgroundColor: theme.colors.background }, children: _jsx("td", { colSpan: 3, style: { padding: '0 0 12px 0' }, children: _jsxs("div", { style: {
|
|
90
|
+
margin: '0 20px',
|
|
91
|
+
padding: '12px',
|
|
92
|
+
borderLeft: `3px solid ${theme.colors.primary}`,
|
|
93
|
+
backgroundColor: theme.colors.cardBackground,
|
|
94
|
+
borderRadius: '0 4px 4px 0'
|
|
95
|
+
}, children: [_jsx("h4", { style: { margin: '0 0 8px 0', fontSize: '12px', textTransform: 'uppercase', color: theme.colors.textSecondary }, children: "Breakdown" }), _jsx("table", { style: { width: '100%', fontSize: '13px' }, children: _jsx("tbody", { children: step.breakdown.map((b, idx) => (_jsxs("tr", { children: [_jsx("td", { style: { padding: '4px 0', color: theme.colors.text }, children: b.label }), _jsx("td", { style: { padding: '4px 0', textAlign: 'right', fontWeight: 600 }, children: b.value.toLocaleString() })] }, idx))) }) })] }) }) }))] }, step.id));
|
|
96
|
+
}) })] }) }))] })] }));
|
|
122
97
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState, useMemo } from 'react';
|
|
3
|
-
import
|
|
2
|
+
import { useState, useMemo, useEffect, useRef } from 'react';
|
|
3
|
+
import * as echarts from 'echarts';
|
|
4
4
|
import { useThemeWithFallback } from '../../utils/useThemeWithFallback';
|
|
5
5
|
export const InteractiveCompositeBlock = ({ title, selector, views }) => {
|
|
6
6
|
const theme = useThemeWithFallback();
|
|
@@ -9,18 +9,19 @@ export const InteractiveCompositeBlock = ({ title, selector, views }) => {
|
|
|
9
9
|
const [viewMode, setViewMode] = useState('split');
|
|
10
10
|
const [filterText, setFilterText] = useState('');
|
|
11
11
|
const [sortConfig, setSortConfig] = useState({ col: '', dir: null });
|
|
12
|
+
// --- Refs ---
|
|
13
|
+
const chartRef = useRef(null);
|
|
14
|
+
const chartInstance = useRef(null);
|
|
12
15
|
// --- Data Access ---
|
|
13
|
-
const
|
|
16
|
+
const rawChartData = views.chart.series[selected] || [];
|
|
14
17
|
const rawTableRows = views.table.rows[selected] || [];
|
|
15
18
|
// --- Logic: Process Table Data ---
|
|
16
19
|
const tableRows = useMemo(() => {
|
|
17
20
|
let data = [...rawTableRows];
|
|
18
|
-
// 1. Filter
|
|
19
21
|
if (filterText) {
|
|
20
22
|
const lower = filterText.toLowerCase();
|
|
21
23
|
data = data.filter(row => Object.values(row).some(val => String(val).toLowerCase().includes(lower)));
|
|
22
24
|
}
|
|
23
|
-
// 2. Sort
|
|
24
25
|
if (sortConfig.col && sortConfig.dir) {
|
|
25
26
|
data.sort((a, b) => {
|
|
26
27
|
const valA = a[sortConfig.col];
|
|
@@ -35,24 +36,141 @@ export const InteractiveCompositeBlock = ({ title, selector, views }) => {
|
|
|
35
36
|
}
|
|
36
37
|
return data;
|
|
37
38
|
}, [rawTableRows, filterText, sortConfig]);
|
|
38
|
-
// --- Handlers ---
|
|
39
39
|
const handleSort = (col) => {
|
|
40
40
|
setSortConfig(prev => ({
|
|
41
41
|
col,
|
|
42
42
|
dir: prev.col === col && prev.dir === 'asc' ? 'desc' : 'asc'
|
|
43
43
|
}));
|
|
44
44
|
};
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
45
|
+
// --- Logic: ECharts Option Generator ---
|
|
46
|
+
const chartOptions = useMemo(() => {
|
|
47
|
+
const { chartType, xKey, yKey } = views.chart;
|
|
48
|
+
const commonOption = {
|
|
49
|
+
tooltip: {
|
|
50
|
+
trigger: 'item',
|
|
51
|
+
backgroundColor: theme.colors.cardBackground,
|
|
52
|
+
borderColor: theme.colors.border,
|
|
53
|
+
textStyle: { color: theme.colors.text }
|
|
54
|
+
},
|
|
55
|
+
grid: { top: 30, right: 30, bottom: 20, left: 40, containLabel: true },
|
|
56
|
+
textStyle: { fontFamily: 'sans-serif' },
|
|
57
|
+
};
|
|
58
|
+
if (chartType === 'line') {
|
|
59
|
+
return {
|
|
60
|
+
...commonOption,
|
|
61
|
+
tooltip: { trigger: 'axis' },
|
|
62
|
+
xAxis: {
|
|
63
|
+
type: 'category',
|
|
64
|
+
// Fallback to empty string if xKey is missing
|
|
65
|
+
data: rawChartData.map(d => xKey ? d[xKey] : ''),
|
|
66
|
+
axisLine: { lineStyle: { color: theme.colors.border } },
|
|
67
|
+
axisLabel: { color: theme.colors.textSecondary }
|
|
68
|
+
},
|
|
69
|
+
yAxis: {
|
|
70
|
+
type: 'value',
|
|
71
|
+
splitLine: { lineStyle: { type: 'dashed', color: theme.colors.border } },
|
|
72
|
+
axisLabel: { color: theme.colors.textSecondary }
|
|
73
|
+
},
|
|
74
|
+
series: [{
|
|
75
|
+
data: rawChartData.map(d => d[yKey]),
|
|
76
|
+
type: 'line',
|
|
77
|
+
smooth: true,
|
|
78
|
+
symbol: 'circle',
|
|
79
|
+
symbolSize: 6,
|
|
80
|
+
itemStyle: { color: theme.colors.primary },
|
|
81
|
+
areaStyle: {
|
|
82
|
+
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
83
|
+
{ offset: 0, color: theme.colors.primary },
|
|
84
|
+
{ offset: 1, color: 'rgba(255, 255, 255, 0)' }
|
|
85
|
+
]),
|
|
86
|
+
opacity: 0.2
|
|
87
|
+
}
|
|
88
|
+
}]
|
|
89
|
+
};
|
|
54
90
|
}
|
|
55
|
-
|
|
91
|
+
if (chartType === 'radial_bar') {
|
|
92
|
+
return {
|
|
93
|
+
...commonOption,
|
|
94
|
+
polar: { radius: [30, '80%'] },
|
|
95
|
+
angleAxis: {
|
|
96
|
+
type: 'category',
|
|
97
|
+
data: rawChartData.map(d => xKey ? d[xKey] : ''),
|
|
98
|
+
startAngle: 75,
|
|
99
|
+
axisLine: { lineStyle: { color: theme.colors.border } },
|
|
100
|
+
axisLabel: { color: theme.colors.textSecondary }
|
|
101
|
+
},
|
|
102
|
+
radiusAxis: { type: 'value', show: false },
|
|
103
|
+
series: [{
|
|
104
|
+
type: 'bar',
|
|
105
|
+
data: rawChartData.map(d => d[yKey]),
|
|
106
|
+
coordinateSystem: 'polar',
|
|
107
|
+
itemStyle: { color: theme.colors.primary },
|
|
108
|
+
label: { show: true, position: 'middle', formatter: '{b}' }
|
|
109
|
+
}]
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
if (chartType === 'treemap') {
|
|
113
|
+
// FIX: Better logic to determine the label (name)
|
|
114
|
+
const treeData = rawChartData.map((d, index) => {
|
|
115
|
+
// 1. Try explicit xKey
|
|
116
|
+
if (xKey && d[xKey])
|
|
117
|
+
return { name: d[xKey], value: d[yKey] };
|
|
118
|
+
// 2. Try guessing common name keys
|
|
119
|
+
const nameCandidate = d.name || d.label || d.category || d.id;
|
|
120
|
+
if (nameCandidate)
|
|
121
|
+
return { name: nameCandidate, value: d[yKey] };
|
|
122
|
+
// 3. Fallback to index so it's unique (prevents "Node Node")
|
|
123
|
+
return { name: `Item ${index + 1}`, value: d[yKey] };
|
|
124
|
+
});
|
|
125
|
+
return {
|
|
126
|
+
...commonOption,
|
|
127
|
+
series: [{
|
|
128
|
+
type: 'treemap',
|
|
129
|
+
data: treeData,
|
|
130
|
+
label: {
|
|
131
|
+
show: true,
|
|
132
|
+
formatter: '{b}' // Show name
|
|
133
|
+
},
|
|
134
|
+
itemStyle: {
|
|
135
|
+
borderColor: theme.colors.cardBackground,
|
|
136
|
+
borderWidth: 2,
|
|
137
|
+
gapWidth: 1
|
|
138
|
+
},
|
|
139
|
+
levels: [
|
|
140
|
+
{ itemStyle: { borderColor: '#555', borderWidth: 4, gapWidth: 4 } },
|
|
141
|
+
{ colorSaturation: [0.3, 0.6], itemStyle: { borderColorSaturation: 0.7, gapWidth: 2, borderWidth: 2 } }
|
|
142
|
+
]
|
|
143
|
+
}]
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
return {};
|
|
147
|
+
}, [views.chart, rawChartData, theme]);
|
|
148
|
+
// --- Effect: Initialize & Update Chart ---
|
|
149
|
+
useEffect(() => {
|
|
150
|
+
if (chartRef.current && !chartInstance.current) {
|
|
151
|
+
chartInstance.current = echarts.init(chartRef.current);
|
|
152
|
+
}
|
|
153
|
+
if (chartInstance.current) {
|
|
154
|
+
chartInstance.current.setOption(chartOptions, true);
|
|
155
|
+
}
|
|
156
|
+
const handleResize = () => chartInstance.current?.resize();
|
|
157
|
+
window.addEventListener('resize', handleResize);
|
|
158
|
+
return () => {
|
|
159
|
+
window.removeEventListener('resize', handleResize);
|
|
160
|
+
if (!chartRef.current && chartInstance.current) {
|
|
161
|
+
chartInstance.current.dispose();
|
|
162
|
+
chartInstance.current = null;
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
}, [chartOptions, viewMode]);
|
|
166
|
+
useEffect(() => {
|
|
167
|
+
if (viewMode === 'table') {
|
|
168
|
+
if (chartInstance.current) {
|
|
169
|
+
chartInstance.current.dispose();
|
|
170
|
+
chartInstance.current = null;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}, [viewMode]);
|
|
56
174
|
const btnStyle = (active) => ({
|
|
57
175
|
padding: '4px 12px',
|
|
58
176
|
backgroundColor: active ? theme.colors.primary : 'transparent',
|
|
@@ -83,7 +201,7 @@ export const InteractiveCompositeBlock = ({ title, selector, views }) => {
|
|
|
83
201
|
borderRadius: theme.borderRadius.medium,
|
|
84
202
|
border: `1px solid ${theme.colors.border}`,
|
|
85
203
|
marginBottom: viewMode === 'split' ? theme.spacing.medium : 0
|
|
86
|
-
}, children: _jsx(
|
|
204
|
+
}, children: _jsx("div", { ref: chartRef, style: { width: '100%', height: '100%' } }) })), (viewMode === 'split' || viewMode === 'table') && (_jsxs("div", { children: [_jsxs("div", { style: { marginBottom: theme.spacing.small, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }, children: [_jsx("input", { type: "text", placeholder: "Filter table data...", value: filterText, onChange: (e) => setFilterText(e.target.value), style: { padding: '4px 8px', borderRadius: theme.borderRadius.small, border: `1px solid ${theme.colors.border}`, width: '200px' } }), _jsxs("span", { style: { fontSize: '11px', color: theme.colors.textSecondary }, children: [tableRows.length, " rows found"] })] }), _jsx("div", { style: {
|
|
87
205
|
overflowX: 'auto',
|
|
88
206
|
backgroundColor: theme.colors.cardBackground,
|
|
89
207
|
borderRadius: theme.borderRadius.medium,
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export { defaultTheme } from './theme/defaultTheme';
|
|
|
4
4
|
export { useThemeWithFallback } from './utils/useThemeWithFallback';
|
|
5
5
|
export type { Theme } from './theme/types';
|
|
6
6
|
export { MDXRenderer } from './MDXRenderer';
|
|
7
|
+
import './styles/base.css';
|
|
7
8
|
export { ProsConsBlock } from './components/smart/ProsConsBlock';
|
|
8
9
|
export { ComparisonBlock } from './components/smart/ComparisonBlock';
|
|
9
10
|
export { FlowBlock } from './components/smart/FlowBlock';
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export { defaultTheme } from './theme/defaultTheme';
|
|
|
5
5
|
export { useThemeWithFallback } from './utils/useThemeWithFallback';
|
|
6
6
|
// Renderer
|
|
7
7
|
export { MDXRenderer } from './MDXRenderer';
|
|
8
|
+
import './styles/base.css';
|
|
8
9
|
// Smart Components
|
|
9
10
|
export { ProsConsBlock } from './components/smart/ProsConsBlock';
|
|
10
11
|
export { ComparisonBlock } from './components/smart/ComparisonBlock';
|
package/dist/theme/themes.js
CHANGED
|
@@ -21,7 +21,7 @@ export const lightTheme = {
|
|
|
21
21
|
h2Size: '24px',
|
|
22
22
|
bodySize: '16px',
|
|
23
23
|
smallSize: '14px',
|
|
24
|
-
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
|
|
24
|
+
fontFamily: '"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
|
|
25
25
|
},
|
|
26
26
|
borderRadius: {
|
|
27
27
|
small: '4px',
|
|
@@ -51,7 +51,7 @@ export const darkTheme = {
|
|
|
51
51
|
h2Size: '24px',
|
|
52
52
|
bodySize: '16px',
|
|
53
53
|
smallSize: '14px',
|
|
54
|
-
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
|
|
54
|
+
fontFamily: '"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
|
|
55
55
|
},
|
|
56
56
|
borderRadius: {
|
|
57
57
|
small: '4px',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amritanshu3011/mdx-renderer",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "Reusable MDX visualization library",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -14,17 +14,20 @@
|
|
|
14
14
|
"author": "Amritanshu",
|
|
15
15
|
"license": "MIT",
|
|
16
16
|
"peerDependencies": {
|
|
17
|
+
"@mdx-js/react": ">=2.0.0",
|
|
17
18
|
"react": ">=18.0.0",
|
|
18
|
-
"react-dom": ">=18.0.0"
|
|
19
|
-
"@mdx-js/react": ">=2.0.0"
|
|
19
|
+
"react-dom": ">=18.0.0"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"recharts": "^2.0.0",
|
|
23
22
|
"echarts": "^5.0.0",
|
|
24
|
-
"lucide-react": "^0.562.0"
|
|
23
|
+
"lucide-react": "^0.562.0",
|
|
24
|
+
"recharts": "^2.0.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
+
"@types/node": "^25.0.9",
|
|
28
|
+
"@types/react": "^18.0.0",
|
|
27
29
|
"typescript": "^5.0.0",
|
|
28
|
-
"
|
|
30
|
+
"vite": "^7.3.1",
|
|
31
|
+
"vite-plugin-dts": "^4.5.4"
|
|
29
32
|
}
|
|
30
33
|
}
|