@amritanshu3011/mdx-renderer 1.0.0 → 1.0.3
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.d.ts +7 -0
- package/dist/MDXRenderer.js +56 -0
- package/dist/components/DynamicVisualizations.d.ts +2 -0
- package/dist/components/DynamicVisualizations.js +17 -0
- package/dist/components/WeatherWidget.d.ts +6 -0
- package/dist/components/WeatherWidget.js +29 -0
- package/dist/components/composite/Dashboard.d.ts +8 -0
- package/dist/components/composite/Dashboard.js +14 -0
- package/dist/components/composite/DataExplorer.d.ts +8 -0
- package/dist/components/composite/DataExplorer.js +37 -0
- package/dist/components/composite/index.d.ts +0 -0
- package/dist/components/composite/index.js +1 -0
- package/dist/components/data/BarChart.d.ts +10 -0
- package/dist/components/data/BarChart.js +17 -0
- package/dist/components/data/LineChart.d.ts +10 -0
- package/dist/components/data/LineChart.js +17 -0
- package/dist/components/data/SimpleChart.d.ts +6 -0
- package/dist/components/data/SimpleChart.js +18 -0
- package/dist/components/data/Table.d.ts +0 -0
- package/dist/components/data/Table.js +1 -0
- package/dist/components/data/index.d.ts +0 -0
- package/dist/components/data/index.js +1 -0
- package/dist/components/index.d.ts +0 -0
- package/dist/components/index.js +1 -0
- package/dist/components/interactive/Accordion.d.ts +8 -0
- package/dist/components/interactive/Accordion.js +29 -0
- package/dist/components/interactive/Modal.d.ts +0 -0
- package/dist/components/interactive/Modal.js +1 -0
- package/dist/components/interactive/Tabs.d.ts +11 -0
- package/dist/components/interactive/Tabs.js +22 -0
- package/dist/components/interactive/index.d.ts +0 -0
- package/dist/components/interactive/index.js +1 -0
- package/dist/components/layout/Card.d.ts +6 -0
- package/dist/components/layout/Card.js +13 -0
- package/dist/components/layout/Container.d.ts +0 -0
- package/dist/components/layout/Container.js +1 -0
- package/dist/components/layout/Grid.d.ts +0 -0
- package/dist/components/layout/Grid.js +1 -0
- package/dist/components/layout/index.d.ts +0 -0
- package/dist/components/layout/index.js +1 -0
- package/dist/components/smart/ComparisonBlock.d.ts +14 -0
- package/dist/components/smart/ComparisonBlock.js +81 -0
- package/dist/components/smart/ConceptTreeBlock.d.ts +11 -0
- package/dist/components/smart/ConceptTreeBlock.js +140 -0
- package/dist/components/smart/FlowBlock.d.ts +11 -0
- package/dist/components/smart/FlowBlock.js +122 -0
- package/dist/components/smart/InteractiveCompositeBlock.d.ts +22 -0
- package/dist/components/smart/InteractiveCompositeBlock.js +102 -0
- package/dist/components/smart/LineChartBlock.d.ts +8 -0
- package/dist/components/smart/LineChartBlock.js +22 -0
- package/dist/components/smart/ProsConsBlock.d.ts +7 -0
- package/dist/components/smart/ProsConsBlock.js +77 -0
- package/dist/components/smart/Sunburst.d.ts +12 -0
- package/dist/components/smart/Sunburst.js +152 -0
- package/dist/components/text/Blockquote.d.ts +7 -0
- package/dist/components/text/Blockquote.js +16 -0
- package/dist/components/text/ComparisonGrid.d.ts +14 -0
- package/dist/components/text/ComparisonGrid.js +46 -0
- package/dist/components/text/Heading.d.ts +7 -0
- package/dist/components/text/Heading.js +13 -0
- package/dist/components/text/List.d.ts +7 -0
- package/dist/components/text/List.js +12 -0
- package/dist/components/text/Paragraph.d.ts +6 -0
- package/dist/components/text/Paragraph.js +13 -0
- package/dist/components/text/ProcessFlow.d.ts +12 -0
- package/dist/components/text/ProcessFlow.js +48 -0
- package/dist/components/text/index.d.ts +0 -0
- package/dist/components/text/index.js +1 -0
- package/dist/context/VisualizationContext.d.ts +13 -0
- package/dist/context/VisualizationContext.js +21 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +34 -0
- package/dist/registry/visualizationRegistry.d.ts +10 -0
- package/dist/registry/visualizationRegistry.js +16 -0
- package/dist/theme/ThemeContext.d.ts +14 -0
- package/dist/theme/ThemeContext.js +19 -0
- package/dist/theme/defaultTheme.d.ts +2 -0
- package/dist/theme/defaultTheme.js +30 -0
- package/dist/theme/index.d.ts +0 -0
- package/dist/theme/index.js +1 -0
- package/dist/theme/themes.d.ts +3 -0
- package/dist/theme/themes.js +60 -0
- package/dist/theme/types.d.ts +30 -0
- package/dist/theme/types.js +1 -0
- package/dist/types/mockLLM.d.ts +5 -0
- package/dist/types/mockLLM.js +109 -0
- package/dist/utils/useThemeWithFallback.d.ts +2 -0
- package/dist/utils/useThemeWithFallback.js +7 -0
- package/dist/utils/withDefaults.d.ts +2 -0
- package/dist/utils/withDefaults.js +4 -0
- package/package.json +29 -24
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useMemo, useEffect } from 'react';
|
|
3
|
+
import { useThemeWithFallback } from '../../utils/useThemeWithFallback';
|
|
4
|
+
export const ConceptTreeBlock = ({ title, root }) => {
|
|
5
|
+
const theme = useThemeWithFallback();
|
|
6
|
+
// --- State ---
|
|
7
|
+
const [viewMode, setViewMode] = useState('tree');
|
|
8
|
+
const [filterText, setFilterText] = useState('');
|
|
9
|
+
const [sortMode, setSortMode] = useState('original');
|
|
10
|
+
const [expanded, setExpanded] = useState(new Set([root.name])); // Root open by default
|
|
11
|
+
const [isPivoted, setIsPivoted] = useState(false); // Used to toggle Level view
|
|
12
|
+
// --- Helpers ---
|
|
13
|
+
// 1. Flatten Tree (for List/Grid/Level views)
|
|
14
|
+
const flattenTree = (node, depth = 0) => {
|
|
15
|
+
let result = [{ node, depth, path: node.name }];
|
|
16
|
+
if (node.children) {
|
|
17
|
+
node.children.forEach(child => {
|
|
18
|
+
result = [...result, ...flattenTree(child, depth + 1)];
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
};
|
|
23
|
+
// 2. Recursive Filter & Sort (For Tree View)
|
|
24
|
+
const processTree = (node) => {
|
|
25
|
+
// A. Check if current node matches
|
|
26
|
+
const matchesSelf = node.name.toLowerCase().includes(filterText.toLowerCase());
|
|
27
|
+
// B. Process Children
|
|
28
|
+
let processedChildren = [];
|
|
29
|
+
if (node.children) {
|
|
30
|
+
processedChildren = node.children
|
|
31
|
+
.map(child => processTree(child))
|
|
32
|
+
.filter((child) => child !== null);
|
|
33
|
+
// Sort Children if needed
|
|
34
|
+
if (sortMode !== 'original') {
|
|
35
|
+
processedChildren.sort((a, b) => sortMode === 'asc' ? a.name.localeCompare(b.name) : b.name.localeCompare(a.name));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// C. Return Node if it matches OR if it has matching children (keep context)
|
|
39
|
+
if (matchesSelf || processedChildren.length > 0) {
|
|
40
|
+
return { ...node, children: processedChildren.length > 0 ? processedChildren : undefined };
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
};
|
|
44
|
+
// --- Memoized Data ---
|
|
45
|
+
const processedRoot = useMemo(() => processTree(root), [root, filterText, sortMode]);
|
|
46
|
+
const flatData = useMemo(() => {
|
|
47
|
+
if (!processedRoot)
|
|
48
|
+
return [];
|
|
49
|
+
return flattenTree(processedRoot);
|
|
50
|
+
}, [processedRoot]);
|
|
51
|
+
// Group by Levels (The "Pivot")
|
|
52
|
+
const dataByLevel = useMemo(() => {
|
|
53
|
+
const levels = {};
|
|
54
|
+
flatData.forEach(item => {
|
|
55
|
+
if (!levels[item.depth])
|
|
56
|
+
levels[item.depth] = [];
|
|
57
|
+
levels[item.depth].push(item);
|
|
58
|
+
});
|
|
59
|
+
return levels;
|
|
60
|
+
}, [flatData]);
|
|
61
|
+
// --- Handlers ---
|
|
62
|
+
const toggleExpand = (name) => {
|
|
63
|
+
const next = new Set(expanded);
|
|
64
|
+
if (next.has(name))
|
|
65
|
+
next.delete(name);
|
|
66
|
+
else
|
|
67
|
+
next.add(name);
|
|
68
|
+
setExpanded(next);
|
|
69
|
+
};
|
|
70
|
+
const expandAll = () => {
|
|
71
|
+
const allNames = new Set(flatData.map(d => d.node.name));
|
|
72
|
+
setExpanded(allNames);
|
|
73
|
+
};
|
|
74
|
+
const collapseAll = () => setExpanded(new Set());
|
|
75
|
+
// Auto-expand when searching
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
if (filterText)
|
|
78
|
+
expandAll();
|
|
79
|
+
}, [filterText]);
|
|
80
|
+
// --- Render Helpers ---
|
|
81
|
+
const btnStyle = (active) => ({
|
|
82
|
+
padding: `${theme.spacing.small} ${theme.spacing.medium}`,
|
|
83
|
+
backgroundColor: active ? theme.colors.primary : 'transparent',
|
|
84
|
+
color: active ? '#fff' : theme.colors.text,
|
|
85
|
+
border: `1px solid ${theme.colors.primary}`,
|
|
86
|
+
borderRadius: theme.borderRadius.small,
|
|
87
|
+
cursor: 'pointer',
|
|
88
|
+
fontSize: theme.typography.smallSize
|
|
89
|
+
});
|
|
90
|
+
// Recursive Renderer (The Original Logic, enhanced)
|
|
91
|
+
const renderNode = (node, level = 0) => {
|
|
92
|
+
const hasChildren = node.children && node.children.length > 0;
|
|
93
|
+
const isExpanded = expanded.has(node.name);
|
|
94
|
+
return (_jsxs("div", { style: { marginLeft: level > 0 ? theme.spacing.large : '0' }, children: [_jsxs("div", { style: {
|
|
95
|
+
display: 'flex',
|
|
96
|
+
alignItems: 'center',
|
|
97
|
+
gap: theme.spacing.small,
|
|
98
|
+
padding: theme.spacing.small,
|
|
99
|
+
backgroundColor: theme.colors.cardBackground,
|
|
100
|
+
border: `1px solid ${theme.colors.border}`,
|
|
101
|
+
borderRadius: theme.borderRadius.small,
|
|
102
|
+
marginBottom: theme.spacing.small,
|
|
103
|
+
color: theme.colors.text,
|
|
104
|
+
fontWeight: level === 0 ? 'bold' : 'normal'
|
|
105
|
+
}, children: [hasChildren ? (_jsx("button", { onClick: () => toggleExpand(node.name), style: {
|
|
106
|
+
background: 'none', border: 'none', cursor: 'pointer',
|
|
107
|
+
color: theme.colors.primary, fontWeight: 'bold', width: '20px'
|
|
108
|
+
}, children: isExpanded ? '▼' : '▶' })) : _jsx("span", { style: { width: '20px' } }), node.name, level === 0 && _jsx("span", { style: { fontSize: '10px', color: theme.colors.textSecondary, border: `1px solid ${theme.colors.border}`, padding: '0 4px', borderRadius: '4px' }, children: "ROOT" })] }), hasChildren && isExpanded && (_jsx("div", { style: { borderLeft: `1px solid ${theme.colors.border}`, marginLeft: '12px', paddingLeft: '12px' }, children: node.children.map(child => renderNode(child, level + 1)) }))] }, node.name));
|
|
109
|
+
};
|
|
110
|
+
return (_jsxs("div", { style: {
|
|
111
|
+
margin: `${theme.spacing.large} 0`,
|
|
112
|
+
border: `1px solid ${theme.colors.border}`,
|
|
113
|
+
borderRadius: theme.borderRadius.medium,
|
|
114
|
+
boxShadow: '0 4px 12px rgba(0,0,0,0.05)',
|
|
115
|
+
overflow: 'hidden'
|
|
116
|
+
}, children: [_jsxs("div", { style: {
|
|
117
|
+
padding: theme.spacing.medium,
|
|
118
|
+
borderBottom: `1px solid ${theme.colors.border}`,
|
|
119
|
+
backgroundColor: theme.colors.background
|
|
120
|
+
}, children: [_jsx("h2", { style: { margin: `0 0 ${theme.spacing.medium} 0`, color: theme.colors.text }, children: title }), _jsxs("div", { style: { display: 'flex', flexWrap: 'wrap', gap: theme.spacing.medium, justifyContent: 'space-between' }, children: [_jsxs("div", { style: { display: 'flex', gap: theme.spacing.small, flexWrap: 'wrap' }, children: [_jsx("input", { type: "text", placeholder: "Filter nodes...", value: filterText, onChange: (e) => setFilterText(e.target.value), style: { padding: theme.spacing.small, borderRadius: theme.borderRadius.small, border: `1px solid ${theme.colors.border}` } }), _jsxs("button", { onClick: () => setSortMode(prev => prev === 'original' ? 'asc' : prev === 'asc' ? 'desc' : 'original'), style: btnStyle(sortMode !== 'original'), children: ["Sort ", sortMode === 'original' ? 'Original' : sortMode === 'asc' ? '(A-Z)' : '(Z-A)'] }), viewMode === 'tree' && (_jsxs(_Fragment, { children: [_jsx("button", { onClick: expandAll, style: btnStyle(false), children: "Expand All" }), _jsx("button", { onClick: collapseAll, style: btnStyle(false), children: "Collapse All" })] }))] }), _jsxs("div", { style: { display: 'flex', gap: theme.spacing.small }, children: [_jsx("button", { onClick: () => { setIsPivoted(!isPivoted); setViewMode(isPivoted ? 'tree' : 'levels'); }, style: btnStyle(isPivoted), children: "Pivot (By Depth)" }), _jsxs("div", { style: { display: 'flex', border: `1px solid ${theme.colors.primary}`, borderRadius: theme.borderRadius.small, overflow: 'hidden' }, children: [_jsx("button", { onClick: () => { setViewMode('tree'); setIsPivoted(false); }, style: { ...btnStyle(viewMode === 'tree'), border: 'none', borderRadius: 0 }, children: "Tree" }), _jsx("button", { onClick: () => { setViewMode('grid'); setIsPivoted(false); }, style: { ...btnStyle(viewMode === 'grid'), border: 'none', borderRadius: 0 }, children: "Grid" }), _jsx("button", { onClick: () => { setViewMode('list'); setIsPivoted(false); }, style: { ...btnStyle(viewMode === 'list'), border: 'none', borderRadius: 0 }, children: "List" })] })] })] })] }), _jsxs("div", { style: { padding: theme.spacing.medium, backgroundColor: theme.colors.background, minHeight: '200px' }, children: [!processedRoot && _jsx("div", { style: { color: theme.colors.textSecondary, textAlign: 'center' }, children: "No matches found." }), viewMode === 'tree' && processedRoot && (renderNode(processedRoot)), viewMode === 'grid' && (_jsx("div", { style: { display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(180px, 1fr))', gap: theme.spacing.medium }, children: flatData.map((item, i) => (_jsxs("div", { style: {
|
|
121
|
+
padding: theme.spacing.medium,
|
|
122
|
+
border: `1px solid ${theme.colors.border}`,
|
|
123
|
+
backgroundColor: theme.colors.cardBackground,
|
|
124
|
+
borderRadius: theme.borderRadius.medium
|
|
125
|
+
}, children: [_jsx("div", { style: { fontWeight: 'bold', color: theme.colors.primary }, children: item.node.name }), _jsxs("div", { style: { fontSize: '10px', color: theme.colors.textSecondary, marginTop: '5px' }, children: ["Depth: ", item.depth] })] }, i))) })), viewMode === 'list' && (_jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: '4px' }, children: flatData.map((item, i) => (_jsxs("div", { style: {
|
|
126
|
+
padding: theme.spacing.small,
|
|
127
|
+
borderBottom: `1px solid ${theme.colors.border}`,
|
|
128
|
+
display: 'flex', justifyContent: 'space-between'
|
|
129
|
+
}, children: [_jsx("span", { children: item.node.name }), _jsxs("span", { style: { color: theme.colors.textSecondary, fontSize: '12px' }, children: ["Level ", item.depth] })] }, i))) })), viewMode === 'levels' && (_jsx("div", { children: Object.entries(dataByLevel).map(([level, items]) => (_jsxs("div", { style: { marginBottom: theme.spacing.large }, children: [_jsxs("h4", { style: {
|
|
130
|
+
color: theme.colors.textSecondary,
|
|
131
|
+
borderBottom: `2px solid ${theme.colors.primary}`,
|
|
132
|
+
marginBottom: theme.spacing.small
|
|
133
|
+
}, children: ["Depth Level ", level] }), _jsx("div", { style: { display: 'flex', flexWrap: 'wrap', gap: theme.spacing.small }, children: items.map((item, i) => (_jsx("span", { style: {
|
|
134
|
+
padding: '4px 8px',
|
|
135
|
+
backgroundColor: theme.colors.cardBackground,
|
|
136
|
+
border: `1px solid ${theme.colors.border}`,
|
|
137
|
+
borderRadius: '12px',
|
|
138
|
+
fontSize: theme.typography.smallSize
|
|
139
|
+
}, children: item.node.name }, i))) })] }, level))) }))] })] }));
|
|
140
|
+
};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import React, { useState, useMemo } from 'react';
|
|
3
|
+
import { useThemeWithFallback } from '../../utils/useThemeWithFallback';
|
|
4
|
+
export const FlowBlock = ({ title, steps }) => {
|
|
5
|
+
const theme = useThemeWithFallback();
|
|
6
|
+
// --- State for Data Manipulation ---
|
|
7
|
+
const [viewMode, setViewMode] = useState('flow');
|
|
8
|
+
const [filterText, setFilterText] = useState('');
|
|
9
|
+
const [sortMode, setSortMode] = useState('original');
|
|
10
|
+
const [isGrouped, setIsGrouped] = useState(false); // Group by First Letter
|
|
11
|
+
const [isPivoted, setIsPivoted] = useState(false); // Only useful in Table view
|
|
12
|
+
// --- Logic: Filter & Sort ---
|
|
13
|
+
const processedData = useMemo(() => {
|
|
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 ---
|
|
44
|
+
const btnStyle = (active) => ({
|
|
45
|
+
padding: `${theme.spacing.small} ${theme.spacing.medium}`,
|
|
46
|
+
backgroundColor: active ? theme.colors.primary : 'transparent',
|
|
47
|
+
color: active ? '#fff' : theme.colors.text,
|
|
48
|
+
border: `1px solid ${theme.colors.primary}`,
|
|
49
|
+
borderRadius: theme.borderRadius.small,
|
|
50
|
+
cursor: 'pointer',
|
|
51
|
+
fontSize: theme.typography.smallSize,
|
|
52
|
+
fontWeight: 'bold'
|
|
53
|
+
});
|
|
54
|
+
return (_jsxs("div", { style: {
|
|
55
|
+
margin: `${theme.spacing.large} 0`,
|
|
56
|
+
border: `1px solid ${theme.colors.border || '#ddd'}`,
|
|
57
|
+
borderRadius: theme.borderRadius.medium,
|
|
58
|
+
boxShadow: '0 4px 12px rgba(0,0,0,0.05)',
|
|
59
|
+
overflow: 'hidden'
|
|
60
|
+
}, children: [_jsxs("div", { style: {
|
|
61
|
+
padding: theme.spacing.medium,
|
|
62
|
+
borderBottom: `1px solid ${theme.colors.border || '#eee'}`,
|
|
63
|
+
backgroundColor: theme.colors.background || '#f9f9f9'
|
|
64
|
+
}, children: [_jsx("h2", { style: {
|
|
65
|
+
color: theme.colors.text,
|
|
66
|
+
margin: `0 0 ${theme.spacing.medium} 0`,
|
|
67
|
+
textAlign: 'left'
|
|
68
|
+
}, children: title }), _jsxs("div", { style: { display: 'flex', flexWrap: 'wrap', gap: theme.spacing.medium, alignItems: 'center', justifyContent: 'space-between' }, children: [_jsxs("div", { style: { display: 'flex', gap: theme.spacing.small, flexWrap: 'wrap' }, children: [_jsx("input", { type: "text", placeholder: "Filter steps...", value: filterText, onChange: (e) => setFilterText(e.target.value), style: {
|
|
69
|
+
padding: theme.spacing.small,
|
|
70
|
+
borderRadius: theme.borderRadius.small,
|
|
71
|
+
border: `1px solid ${theme.colors.border || '#ccc'}`
|
|
72
|
+
} }), _jsxs("button", { onClick: () => setSortMode(prev => prev === 'original' ? 'asc' : prev === 'asc' ? 'desc' : 'original'), style: btnStyle(sortMode !== 'original'), children: ["Sort ", sortMode === 'original' ? 'Original' : sortMode === 'asc' ? '(A-Z)' : '(Z-A)'] }), _jsx("button", { onClick: () => setIsGrouped(!isGrouped), style: btnStyle(isGrouped), children: isGrouped ? 'Ungroup' : 'Group (A-Z)' })] }), _jsxs("div", { style: { display: 'flex', gap: theme.spacing.small }, children: [viewMode === 'table' && (_jsx("button", { onClick: () => setIsPivoted(!isPivoted), style: btnStyle(isPivoted), children: "Pivot Data" })), _jsx("div", { style: { display: 'flex', border: `1px solid ${theme.colors.primary}`, borderRadius: theme.borderRadius.small, overflow: 'hidden' }, children: ['flow', 'grid', 'list', 'table'].map((v) => (_jsx("button", { onClick: () => setViewMode(v), style: {
|
|
73
|
+
...btnStyle(viewMode === v),
|
|
74
|
+
border: 'none',
|
|
75
|
+
borderRadius: 0,
|
|
76
|
+
textTransform: 'capitalize'
|
|
77
|
+
}, children: v }, v))) })] })] })] }), _jsxs("div", { style: { padding: theme.spacing.medium, backgroundColor: theme.colors.background }, children: [Object.entries(groupedData).map(([groupTitle, groupSteps]) => (_jsxs("div", { style: { marginBottom: theme.spacing.large }, children: [isGrouped && (_jsxs("h4", { style: {
|
|
78
|
+
color: theme.colors.textSecondary,
|
|
79
|
+
borderBottom: `1px solid ${theme.colors.border || '#eee'}`,
|
|
80
|
+
marginBottom: theme.spacing.medium
|
|
81
|
+
}, children: ["Group: ", groupTitle] })), viewMode === 'flow' && (_jsxs("div", { style: {
|
|
82
|
+
display: 'flex',
|
|
83
|
+
alignItems: 'center',
|
|
84
|
+
gap: theme.spacing.medium,
|
|
85
|
+
overflowX: 'auto',
|
|
86
|
+
padding: theme.spacing.small
|
|
87
|
+
}, children: [groupSteps.map((step, i) => (_jsxs(React.Fragment, { children: [_jsxs("div", { style: {
|
|
88
|
+
flex: '0 0 220px',
|
|
89
|
+
padding: theme.spacing.medium,
|
|
90
|
+
backgroundColor: theme.colors.cardBackground,
|
|
91
|
+
border: `2px solid ${theme.colors.primary}`,
|
|
92
|
+
borderRadius: theme.borderRadius.medium,
|
|
93
|
+
boxShadow: '0 2px 5px rgba(0,0,0,0.1)'
|
|
94
|
+
}, children: [_jsxs("div", { style: {
|
|
95
|
+
fontWeight: 'bold',
|
|
96
|
+
color: theme.colors.primary,
|
|
97
|
+
marginBottom: theme.spacing.small,
|
|
98
|
+
fontSize: theme.typography.bodySize
|
|
99
|
+
}, children: [i + 1, ". ", step.title] }), _jsx("div", { style: {
|
|
100
|
+
color: theme.colors.textSecondary,
|
|
101
|
+
fontSize: theme.typography.smallSize,
|
|
102
|
+
lineHeight: '1.5'
|
|
103
|
+
}, children: step.description })] }), i < groupSteps.length - 1 && (_jsx("div", { style: {
|
|
104
|
+
color: theme.colors.primary,
|
|
105
|
+
fontSize: '28px',
|
|
106
|
+
fontWeight: 'bold',
|
|
107
|
+
minWidth: '20px'
|
|
108
|
+
}, children: "\u2192" }))] }, i))), groupSteps.length === 0 && _jsx("div", { style: { color: theme.colors.textSecondary }, children: "No steps match filter." })] })), viewMode === 'grid' && (_jsx("div", { style: { display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(220px, 1fr))', gap: theme.spacing.medium }, children: groupSteps.map((step, i) => (_jsxs("div", { style: {
|
|
109
|
+
padding: theme.spacing.medium,
|
|
110
|
+
backgroundColor: theme.colors.cardBackground,
|
|
111
|
+
border: `1px solid ${theme.colors.border || '#ddd'}`,
|
|
112
|
+
borderRadius: theme.borderRadius.medium
|
|
113
|
+
}, children: [_jsx("div", { style: { fontWeight: 'bold', color: theme.colors.text }, children: step.title }), _jsx("hr", { style: { margin: '8px 0', border: '0', borderTop: `1px solid ${theme.colors.border || '#eee'}` } }), _jsx("div", { style: { color: theme.colors.textSecondary, fontSize: theme.typography.smallSize }, children: step.description })] }, i))) })), viewMode === 'list' && (_jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: theme.spacing.small }, children: groupSteps.map((step, i) => (_jsxs("div", { style: {
|
|
114
|
+
padding: theme.spacing.medium,
|
|
115
|
+
backgroundColor: theme.colors.cardBackground,
|
|
116
|
+
borderLeft: `4px solid ${theme.colors.primary}`,
|
|
117
|
+
borderRadius: theme.borderRadius.small,
|
|
118
|
+
display: 'flex',
|
|
119
|
+
alignItems: 'center',
|
|
120
|
+
justifyContent: 'space-between'
|
|
121
|
+
}, children: [_jsxs("span", { style: { fontWeight: 'bold', color: theme.colors.text }, children: [i + 1, ". ", step.title] }), _jsx("span", { style: { color: theme.colors.textSecondary }, children: step.description })] }, i))) })), viewMode === 'table' && (_jsx("div", { style: { overflowX: 'auto' }, children: _jsxs("table", { style: { width: '100%', borderCollapse: 'collapse', fontSize: theme.typography.smallSize }, children: [!isPivoted && (_jsxs(_Fragment, { children: [_jsx("thead", { children: _jsxs("tr", { style: { backgroundColor: theme.colors.background, borderBottom: `2px solid ${theme.colors.primary}` }, children: [_jsx("th", { style: { padding: theme.spacing.small, textAlign: 'left' }, children: "Step #" }), _jsx("th", { style: { padding: theme.spacing.small, textAlign: 'left' }, children: "Title" }), _jsx("th", { style: { padding: theme.spacing.small, textAlign: 'left' }, children: "Description" })] }) }), _jsx("tbody", { children: groupSteps.map((step, i) => (_jsxs("tr", { style: { borderBottom: `1px solid ${theme.colors.border || '#eee'}` }, children: [_jsx("td", { style: { padding: theme.spacing.small }, children: i + 1 }), _jsx("td", { style: { padding: theme.spacing.small, fontWeight: 'bold' }, children: step.title }), _jsx("td", { style: { padding: theme.spacing.small, color: theme.colors.textSecondary }, children: step.description })] }, i))) })] })), isPivoted && (_jsxs("tbody", { children: [_jsxs("tr", { style: { borderBottom: `1px solid ${theme.colors.border || '#eee'}` }, children: [_jsx("th", { style: { padding: theme.spacing.small, textAlign: 'right', backgroundColor: theme.colors.background }, children: "Title" }), groupSteps.map((step, i) => (_jsx("td", { style: { padding: theme.spacing.small, fontWeight: 'bold', borderLeft: `1px solid ${theme.colors.border}` }, children: step.title }, i)))] }), _jsxs("tr", { children: [_jsx("th", { style: { padding: theme.spacing.small, textAlign: 'right', backgroundColor: theme.colors.background }, children: "Description" }), groupSteps.map((step, i) => (_jsx("td", { style: { padding: theme.spacing.small, color: theme.colors.textSecondary, borderLeft: `1px solid ${theme.colors.border}` }, children: step.description }, i)))] })] }))] }) }))] }, groupTitle))), processedData.length === 0 && (_jsxs("div", { style: { textAlign: 'center', padding: theme.spacing.large, color: theme.colors.textSecondary }, children: ["No results found for \"", filterText, "\""] }))] })] }));
|
|
122
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface InteractiveCompositeProps {
|
|
3
|
+
title: string;
|
|
4
|
+
selector: {
|
|
5
|
+
label: string;
|
|
6
|
+
options: string[];
|
|
7
|
+
default: string;
|
|
8
|
+
};
|
|
9
|
+
views: {
|
|
10
|
+
chart: {
|
|
11
|
+
chartType: 'line' | 'radial_bar' | 'treemap';
|
|
12
|
+
xKey?: string;
|
|
13
|
+
yKey: string;
|
|
14
|
+
series: Record<string, any[]>;
|
|
15
|
+
};
|
|
16
|
+
table: {
|
|
17
|
+
columns: string[];
|
|
18
|
+
rows: Record<string, Record<string, string | number>[]>;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export declare const InteractiveCompositeBlock: React.FC<InteractiveCompositeProps>;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useMemo } from 'react';
|
|
3
|
+
import { LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer, RadialBarChart, RadialBar, Treemap } from 'recharts';
|
|
4
|
+
import { useThemeWithFallback } from '../../utils/useThemeWithFallback';
|
|
5
|
+
export const InteractiveCompositeBlock = ({ title, selector, views }) => {
|
|
6
|
+
const theme = useThemeWithFallback();
|
|
7
|
+
// --- State ---
|
|
8
|
+
const [selected, setSelected] = useState(selector.default);
|
|
9
|
+
const [viewMode, setViewMode] = useState('split');
|
|
10
|
+
const [filterText, setFilterText] = useState('');
|
|
11
|
+
const [sortConfig, setSortConfig] = useState({ col: '', dir: null });
|
|
12
|
+
// --- Data Access ---
|
|
13
|
+
const chartData = views.chart.series[selected] || [];
|
|
14
|
+
const rawTableRows = views.table.rows[selected] || [];
|
|
15
|
+
// --- Logic: Process Table Data ---
|
|
16
|
+
const tableRows = useMemo(() => {
|
|
17
|
+
let data = [...rawTableRows];
|
|
18
|
+
// 1. Filter
|
|
19
|
+
if (filterText) {
|
|
20
|
+
const lower = filterText.toLowerCase();
|
|
21
|
+
data = data.filter(row => Object.values(row).some(val => String(val).toLowerCase().includes(lower)));
|
|
22
|
+
}
|
|
23
|
+
// 2. Sort
|
|
24
|
+
if (sortConfig.col && sortConfig.dir) {
|
|
25
|
+
data.sort((a, b) => {
|
|
26
|
+
const valA = a[sortConfig.col];
|
|
27
|
+
const valB = b[sortConfig.col];
|
|
28
|
+
if (typeof valA === 'number' && typeof valB === 'number') {
|
|
29
|
+
return sortConfig.dir === 'asc' ? valA - valB : valB - valA;
|
|
30
|
+
}
|
|
31
|
+
return sortConfig.dir === 'asc'
|
|
32
|
+
? String(valA).localeCompare(String(valB))
|
|
33
|
+
: String(valB).localeCompare(String(valA));
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return data;
|
|
37
|
+
}, [rawTableRows, filterText, sortConfig]);
|
|
38
|
+
// --- Handlers ---
|
|
39
|
+
const handleSort = (col) => {
|
|
40
|
+
setSortConfig(prev => ({
|
|
41
|
+
col,
|
|
42
|
+
dir: prev.col === col && prev.dir === 'asc' ? 'desc' : 'asc'
|
|
43
|
+
}));
|
|
44
|
+
};
|
|
45
|
+
const renderChart = () => {
|
|
46
|
+
switch (views.chart.chartType) {
|
|
47
|
+
case 'radial_bar':
|
|
48
|
+
return (_jsxs(RadialBarChart, { innerRadius: "30%", outerRadius: "90%", data: chartData, children: [_jsx(RadialBar, { dataKey: views.chart.yKey, fill: theme.colors.primary }), _jsx(Tooltip, {})] }));
|
|
49
|
+
case 'treemap':
|
|
50
|
+
return (_jsx(Treemap, { data: chartData, dataKey: views.chart.yKey, stroke: theme.colors.border, fill: theme.colors.primary, children: _jsx(Tooltip, {}) }));
|
|
51
|
+
case 'line':
|
|
52
|
+
default:
|
|
53
|
+
return (_jsxs(LineChart, { data: chartData, children: [views.chart.xKey && _jsx(XAxis, { dataKey: views.chart.xKey, tick: { fill: theme.colors.textSecondary } }), _jsx(YAxis, { tick: { fill: theme.colors.textSecondary } }), _jsx(Tooltip, {}), _jsx(Line, { type: "monotone", dataKey: views.chart.yKey, stroke: theme.colors.primary, strokeWidth: 2, dot: false })] }));
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const btnStyle = (active) => ({
|
|
57
|
+
padding: '4px 12px',
|
|
58
|
+
backgroundColor: active ? theme.colors.primary : 'transparent',
|
|
59
|
+
color: active ? '#fff' : theme.colors.text,
|
|
60
|
+
border: `1px solid ${theme.colors.border}`,
|
|
61
|
+
borderRadius: 0,
|
|
62
|
+
cursor: 'pointer',
|
|
63
|
+
fontSize: theme.typography.smallSize
|
|
64
|
+
});
|
|
65
|
+
return (_jsxs("div", { style: {
|
|
66
|
+
margin: `${theme.spacing.large} 0`,
|
|
67
|
+
border: `1px solid ${theme.colors.border}`,
|
|
68
|
+
borderRadius: theme.borderRadius.medium,
|
|
69
|
+
overflow: 'hidden',
|
|
70
|
+
boxShadow: '0 4px 12px rgba(0,0,0,0.05)'
|
|
71
|
+
}, children: [_jsxs("div", { style: {
|
|
72
|
+
padding: theme.spacing.medium,
|
|
73
|
+
backgroundColor: theme.colors.background,
|
|
74
|
+
borderBottom: `1px solid ${theme.colors.border}`,
|
|
75
|
+
display: 'flex', flexWrap: 'wrap', gap: theme.spacing.medium, alignItems: 'center', justifyContent: 'space-between'
|
|
76
|
+
}, children: [_jsx("div", { children: _jsx("h2", { style: { margin: 0, fontSize: theme.typography.h2Size, color: theme.colors.text }, children: title }) }), _jsxs("div", { style: { display: 'flex', gap: theme.spacing.medium, alignItems: 'center', flexWrap: 'wrap' }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: theme.spacing.small }, children: [_jsxs("span", { style: { fontSize: '12px', color: theme.colors.textSecondary }, children: [selector.label, ":"] }), _jsx("select", { value: selected, onChange: (e) => setSelected(e.target.value), style: {
|
|
77
|
+
padding: '4px 8px', borderRadius: theme.borderRadius.small,
|
|
78
|
+
border: `1px solid ${theme.colors.border}`, backgroundColor: theme.colors.cardBackground
|
|
79
|
+
}, children: selector.options.map(o => _jsx("option", { value: o, children: o }, o)) })] }), _jsxs("div", { style: { display: 'flex', border: `1px solid ${theme.colors.primary}`, borderRadius: theme.borderRadius.small, overflow: 'hidden' }, children: [_jsx("button", { onClick: () => setViewMode('split'), style: btnStyle(viewMode === 'split'), children: "Split" }), _jsx("button", { onClick: () => setViewMode('chart'), style: btnStyle(viewMode === 'chart'), children: "Chart" }), _jsx("button", { onClick: () => setViewMode('table'), style: btnStyle(viewMode === 'table'), children: "Table" })] })] })] }), _jsxs("div", { style: { padding: theme.spacing.medium, backgroundColor: theme.colors.background }, children: [(viewMode === 'split' || viewMode === 'chart') && (_jsx("div", { style: {
|
|
80
|
+
height: viewMode === 'chart' ? 450 : 320,
|
|
81
|
+
padding: theme.spacing.medium,
|
|
82
|
+
backgroundColor: theme.colors.cardBackground,
|
|
83
|
+
borderRadius: theme.borderRadius.medium,
|
|
84
|
+
border: `1px solid ${theme.colors.border}`,
|
|
85
|
+
marginBottom: viewMode === 'split' ? theme.spacing.medium : 0
|
|
86
|
+
}, children: _jsx(ResponsiveContainer, { width: "100%", height: "100%", children: renderChart() }) })), (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
|
+
overflowX: 'auto',
|
|
88
|
+
backgroundColor: theme.colors.cardBackground,
|
|
89
|
+
borderRadius: theme.borderRadius.medium,
|
|
90
|
+
border: `1px solid ${theme.colors.border}`,
|
|
91
|
+
maxHeight: viewMode === 'table' ? '500px' : '300px',
|
|
92
|
+
overflowY: 'auto'
|
|
93
|
+
}, children: _jsxs("table", { style: { width: '100%', borderCollapse: 'collapse' }, children: [_jsx("thead", { style: { position: 'sticky', top: 0, backgroundColor: theme.colors.cardBackground, zIndex: 1 }, children: _jsx("tr", { children: views.table.columns.map(col => (_jsxs("th", { onClick: () => handleSort(col), style: {
|
|
94
|
+
textAlign: 'left',
|
|
95
|
+
padding: theme.spacing.small,
|
|
96
|
+
borderBottom: `2px solid ${theme.colors.border}`,
|
|
97
|
+
color: theme.colors.text,
|
|
98
|
+
cursor: 'pointer',
|
|
99
|
+
userSelect: 'none',
|
|
100
|
+
minWidth: '100px'
|
|
101
|
+
}, children: [col, " ", sortConfig.col === col ? (sortConfig.dir === 'asc' ? '↑' : '↓') : ''] }, col))) }) }), _jsxs("tbody", { children: [tableRows.map((row, i) => (_jsx("tr", { style: { backgroundColor: i % 2 === 0 ? 'transparent' : 'rgba(0,0,0,0.02)' }, children: views.table.columns.map(col => (_jsx("td", { style: { padding: theme.spacing.small, borderBottom: `1px solid ${theme.colors.border}`, color: theme.colors.textSecondary }, children: row[col] }, col))) }, i))), tableRows.length === 0 && (_jsx("tr", { children: _jsx("td", { colSpan: views.table.columns.length, style: { padding: '20px', textAlign: 'center', color: theme.colors.textSecondary }, children: "No matches found." }) }))] })] }) })] }))] })] }));
|
|
102
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts';
|
|
3
|
+
import { useThemeWithFallback } from '../../utils/useThemeWithFallback';
|
|
4
|
+
export const LineChartBlock = ({ title, xKey, yKey, points }) => {
|
|
5
|
+
const theme = useThemeWithFallback();
|
|
6
|
+
return (_jsxs("div", { style: { margin: `${theme.spacing.large} 0` }, children: [_jsx("h2", { style: {
|
|
7
|
+
color: theme.colors.text,
|
|
8
|
+
marginBottom: theme.spacing.medium,
|
|
9
|
+
textAlign: 'center'
|
|
10
|
+
}, children: title }), _jsx("div", { style: {
|
|
11
|
+
height: 320,
|
|
12
|
+
padding: theme.spacing.medium,
|
|
13
|
+
backgroundColor: theme.colors.cardBackground,
|
|
14
|
+
borderRadius: theme.borderRadius.medium,
|
|
15
|
+
border: `1px solid ${theme.colors.border}`
|
|
16
|
+
}, children: _jsx(ResponsiveContainer, { width: "100%", height: "100%", children: _jsxs(LineChart, { data: points, children: [_jsx(XAxis, { dataKey: xKey, tick: { fill: theme.colors.textSecondary } }), _jsx(YAxis, { tick: { fill: theme.colors.textSecondary } }), _jsx(Tooltip, { contentStyle: {
|
|
17
|
+
backgroundColor: theme.colors.cardBackground,
|
|
18
|
+
border: `1px solid ${theme.colors.border}`,
|
|
19
|
+
borderRadius: theme.borderRadius.small,
|
|
20
|
+
color: theme.colors.text
|
|
21
|
+
} }), _jsx(Line, { type: "monotone", dataKey: yKey, stroke: theme.colors.primary, strokeWidth: 2, dot: false })] }) }) })] }));
|
|
22
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useMemo } from 'react';
|
|
3
|
+
import { useThemeWithFallback } from '../../utils/useThemeWithFallback';
|
|
4
|
+
export const ProsConsBlock = ({ title, pros, cons }) => {
|
|
5
|
+
const theme = useThemeWithFallback();
|
|
6
|
+
// --- State ---
|
|
7
|
+
const [filterText, setFilterText] = useState('');
|
|
8
|
+
const [sortMode, setSortMode] = useState('original');
|
|
9
|
+
const [isPivoted, setIsPivoted] = useState(false); // Merges lists into one
|
|
10
|
+
const [viewMode, setViewMode] = useState('split');
|
|
11
|
+
// --- Data Processing ---
|
|
12
|
+
const processedData = useMemo(() => {
|
|
13
|
+
// 1. Unify data structure
|
|
14
|
+
const allItems = [
|
|
15
|
+
...pros.map(t => ({ text: t, type: 'pro' })),
|
|
16
|
+
...cons.map(t => ({ text: t, type: 'con' }))
|
|
17
|
+
];
|
|
18
|
+
// 2. Filter
|
|
19
|
+
let filtered = allItems;
|
|
20
|
+
if (filterText) {
|
|
21
|
+
filtered = allItems.filter(i => i.text.toLowerCase().includes(filterText.toLowerCase()));
|
|
22
|
+
}
|
|
23
|
+
// 3. Sort
|
|
24
|
+
if (sortMode !== 'original') {
|
|
25
|
+
filtered.sort((a, b) => sortMode === 'asc'
|
|
26
|
+
? a.text.localeCompare(b.text)
|
|
27
|
+
: b.text.localeCompare(a.text));
|
|
28
|
+
}
|
|
29
|
+
return filtered;
|
|
30
|
+
}, [pros, cons, filterText, sortMode]);
|
|
31
|
+
// Derived arrays for "Split" view
|
|
32
|
+
const currentPros = processedData.filter(i => i.type === 'pro');
|
|
33
|
+
const currentCons = processedData.filter(i => i.type === 'con');
|
|
34
|
+
// --- Styles ---
|
|
35
|
+
const btnStyle = (active) => ({
|
|
36
|
+
padding: '4px 12px',
|
|
37
|
+
backgroundColor: active ? theme.colors.primary : 'transparent',
|
|
38
|
+
color: active ? '#fff' : theme.colors.text,
|
|
39
|
+
border: `1px solid ${theme.colors.border}`,
|
|
40
|
+
borderRadius: theme.borderRadius.small,
|
|
41
|
+
cursor: 'pointer',
|
|
42
|
+
fontSize: theme.typography.smallSize
|
|
43
|
+
});
|
|
44
|
+
const badgeStyle = (type) => ({
|
|
45
|
+
display: 'inline-block',
|
|
46
|
+
padding: '2px 8px',
|
|
47
|
+
borderRadius: '12px',
|
|
48
|
+
fontSize: '11px',
|
|
49
|
+
fontWeight: 'bold',
|
|
50
|
+
backgroundColor: type === 'pro' ? 'rgba(40, 167, 69, 0.1)' : 'rgba(220, 53, 69, 0.1)',
|
|
51
|
+
color: type === 'pro' ? '#28a745' : '#dc3545',
|
|
52
|
+
border: `1px solid ${type === 'pro' ? '#28a745' : '#dc3545'}`
|
|
53
|
+
});
|
|
54
|
+
return (_jsxs("div", { style: {
|
|
55
|
+
margin: `${theme.spacing.large} 0`,
|
|
56
|
+
border: `1px solid ${theme.colors.border}`,
|
|
57
|
+
borderRadius: theme.borderRadius.medium,
|
|
58
|
+
overflow: 'hidden'
|
|
59
|
+
}, children: [_jsxs("div", { style: {
|
|
60
|
+
padding: theme.spacing.medium,
|
|
61
|
+
backgroundColor: theme.colors.background,
|
|
62
|
+
borderBottom: `1px solid ${theme.colors.border}`,
|
|
63
|
+
display: 'flex', flexWrap: 'wrap', gap: theme.spacing.medium, alignItems: 'center', justifyContent: 'space-between'
|
|
64
|
+
}, children: [_jsx("h2", { style: { margin: 0, fontSize: theme.typography.h2Size, color: theme.colors.text }, children: title }), _jsxs("div", { style: { display: 'flex', gap: theme.spacing.small }, children: [_jsx("input", { type: "text", placeholder: "Filter...", value: filterText, onChange: (e) => setFilterText(e.target.value), style: { padding: '4px 8px', borderRadius: theme.borderRadius.small, border: `1px solid ${theme.colors.border}` } }), _jsx("button", { onClick: () => setSortMode(p => p === 'original' ? 'asc' : 'original'), style: btnStyle(sortMode === 'asc'), children: "Sort A-Z" }), _jsx("button", { onClick: () => setIsPivoted(!isPivoted), style: btnStyle(isPivoted), children: isPivoted ? 'Split View' : 'Pivot (Merge)' })] })] }), _jsx("div", { style: { padding: theme.spacing.medium, backgroundColor: theme.colors.background }, children: isPivoted ? (_jsxs("table", { style: { width: '100%', borderCollapse: 'collapse' }, children: [_jsx("thead", { children: _jsxs("tr", { style: { textAlign: 'left', borderBottom: `2px solid ${theme.colors.border}` }, children: [_jsx("th", { style: { padding: theme.spacing.small }, children: "Type" }), _jsx("th", { style: { padding: theme.spacing.small }, children: "Point" })] }) }), _jsxs("tbody", { children: [processedData.map((item, i) => (_jsxs("tr", { style: { borderBottom: `1px solid ${theme.colors.border}` }, children: [_jsx("td", { style: { padding: theme.spacing.small, width: '80px' }, children: _jsx("span", { style: badgeStyle(item.type), children: item.type.toUpperCase() }) }), _jsx("td", { style: { padding: theme.spacing.small, color: theme.colors.text }, children: item.text })] }, i))), processedData.length === 0 && _jsx("tr", { children: _jsx("td", { colSpan: 2, style: { textAlign: 'center', padding: '20px' }, children: "No matches." }) })] })] })) : (
|
|
65
|
+
/* VIEW 2: ORIGINAL SPLIT (Grid) */
|
|
66
|
+
_jsxs("div", { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: theme.spacing.medium }, children: [_jsxs("div", { style: {
|
|
67
|
+
padding: theme.spacing.medium,
|
|
68
|
+
backgroundColor: theme.colors.cardBackground,
|
|
69
|
+
border: `2px solid #28a745`,
|
|
70
|
+
borderRadius: theme.borderRadius.medium
|
|
71
|
+
}, children: [_jsxs("h3", { style: { color: '#28a745', margin: `0 0 ${theme.spacing.medium} 0`, display: 'flex', alignItems: 'center', gap: '8px' }, children: ["\u2713 Pros (", currentPros.length, ")"] }), _jsx("ul", { style: { margin: 0, paddingLeft: theme.spacing.medium, color: theme.colors.text }, children: currentPros.map((item, i) => (_jsx("li", { style: { marginBottom: theme.spacing.small }, children: item.text }, i))) })] }), _jsxs("div", { style: {
|
|
72
|
+
padding: theme.spacing.medium,
|
|
73
|
+
backgroundColor: theme.colors.cardBackground,
|
|
74
|
+
border: `2px solid #dc3545`,
|
|
75
|
+
borderRadius: theme.borderRadius.medium
|
|
76
|
+
}, children: [_jsxs("h3", { style: { color: '#dc3545', margin: `0 0 ${theme.spacing.medium} 0`, display: 'flex', alignItems: 'center', gap: '8px' }, children: ["\u2717 Cons (", currentCons.length, ")"] }), _jsx("ul", { style: { margin: 0, paddingLeft: theme.spacing.medium, color: theme.colors.text }, children: currentCons.map((item, i) => (_jsx("li", { style: { marginBottom: theme.spacing.small }, children: item.text }, i))) })] })] })) })] }));
|
|
77
|
+
};
|