visualifyjs 2.5.3-2.dev → 2.5.3-9-dev
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.
Potentially problematic release.
This version of visualifyjs might be problematic. Click here for more details.
- package/.github/workflows/{static.yml.bak → build.yaml} +51 -51
- package/LICENSE +674 -674
- package/README.md +40 -58
- package/config-overrides.js +31 -31
- package/dist/visualify.js +3 -3
- package/docs/CLI.md +15 -0
- package/docs/{docs/README.md → README.md} +41 -65
- package/docs/{docs/Rechart → Rechart}/bar.md +190 -190
- package/docs/{docs/Rechart → Rechart}/funnel.md +193 -241
- package/docs/{docs/Rechart → Rechart}/line.md +355 -355
- package/docs/{docs/Rechart → Rechart}/pie.md +225 -225
- package/docs/{docs/Rechart → Rechart}/radar.md +253 -253
- package/docs/{docs/_404.md → _404.md} +51 -51
- package/docs/{docs/_coverpage.md → _coverpage.md} +11 -11
- package/docs/{docs/_sidebar.md → _sidebar.md} +42 -44
- package/docs/{docs/components → components}/dotBio.md +34 -34
- package/docs/{docs/components → components}/echart.md +82 -82
- package/docs/{docs/components → components}/html.md +34 -34
- package/docs/{docs/components → components}/macaron.md +145 -145
- package/docs/components/markdown.md +0 -0
- package/docs/{docs/components → components}/more.md +142 -142
- package/docs/{docs/components → components}/plotly.md +62 -62
- package/docs/{docs/components → components}/scatterL.md +70 -70
- package/docs/{docs/components → components}/visium.md +56 -56
- package/docs/{docs/configuration.md → configuration.md} +123 -121
- package/docs/{docs/deploy.md → deploy.md} +23 -31
- package/docs/index.html +70 -70
- package/docs/log.md +1 -0
- package/docs/manifest.json +23 -23
- package/docs/{docs/more-pages.md → more-pages.md} +23 -23
- package/docs/{docs/quickstart.md → quickstart.md} +115 -124
- package/docs/{docs/rechart-attributes.md → rechart-attributes.md} +74 -74
- package/docs/{docs/rechart-basic-usage.md → rechart-basic-usage.md} +162 -162
- package/docs/static/css/fluff-stuff.css +169 -169
- package/docs/static/css/font-awesome.min.css +4 -4
- package/docs/static/css/visualify.css +25 -25
- package/docs/static/js/configuration.js +448 -448
- package/docs/static/js/visualify.js +24 -23
- package/docs/theme.md +3 -0
- package/package.json +74 -83
- package/rollup.config.mjs +75 -75
- package/src/_css/404.css +115 -115
- package/src/_css/App.css +37 -37
- package/src/_css/autoSuggestion.css +26 -26
- package/src/_css/circular-progress.css +32 -32
- package/src/_css/index.css +36 -36
- package/src/_css/modern.css +24 -24
- package/src/_media/corner.svg +8 -8
- package/src/_media/download.svg +3 -3
- package/src/_media/logo.svg +14 -14
- package/src/_test/App.test.js +15 -15
- package/src/_utils/reportWebVitals.js +13 -13
- package/src/core/appContext.js +27 -27
- package/src/core/components/Scatter.js +188 -188
- package/src/core/components/ScatterBio.js +572 -572
- package/src/core/components/VisiumPlot.js +165 -165
- package/src/core/components/browser.js +42 -42
- package/src/core/components/dotplot.js +413 -413
- package/src/core/components/html.js +29 -29
- package/src/core/components/list.js +178 -178
- package/src/core/components/macaron.js +201 -201
- package/src/core/components/markdown.js +56 -56
- package/src/core/components/parser.scatterBio.js +579 -587
- package/src/core/components/ratio.js +80 -80
- package/src/core/components/scatterL.js +173 -173
- package/src/core/components/searchbar.js +131 -131
- package/src/core/components/selection.js +193 -193
- package/src/core/components/timeline.js +281 -281
- package/src/core/components/visium.js +97 -97
- package/src/core/fetch/condfetch.js +82 -82
- package/src/core/fetch/fetch.js +92 -92
- package/src/core/fetch/json.js +29 -29
- package/src/core/fetch/vfetch.js +42 -42
- package/src/core/liveEditor.js +44 -44
- package/src/core/modules/codeEditorWithPreview.js +104 -104
- package/src/core/modules/echarts/common.js +20 -20
- package/src/core/modules/echarts/presetHandler.js +41 -41
- package/src/core/modules/echarts/presets/esodev.chromium.js +172 -172
- package/src/core/modules/echarts/presets/esodev.codex.js +130 -130
- package/src/core/modules/echarts/presets/esodev.visium.js +123 -123
- package/src/core/modules/echarts/presets/mmtrbc.js +186 -186
- package/src/core/modules/echarts.js +71 -71
- package/src/core/modules/echartsUtils.js +43 -43
- package/src/core/modules/echartswitcher.js +152 -152
- package/src/core/modules/replotly/presetHandler.js +24 -24
- package/src/core/modules/replotly/presets/minimum.js +18 -18
- package/src/core/modules/replotly/presets/mmtrbc.dot.js +114 -114
- package/src/core/modules/replotly/presets/mmtrbc.violin.js +100 -100
- package/src/core/modules/replotly.js +71 -71
- package/src/core/pages/404.js +50 -50
- package/src/core/pages/error.js +27 -27
- package/src/core/pages/jsonPage.js +62 -62
- package/src/core/pages/loading.js +44 -44
- package/src/core/parser/echart.data.js +183 -183
- package/src/core/parser/echart.features.js +125 -125
- package/src/core/parser/echart.general.js +143 -147
- package/src/core/parser/echart.hilbert.js +57 -57
- package/src/core/parser/echart.parser.js +210 -210
- package/src/core/parser/echart.series.js +67 -67
- package/src/core/parser/echart.types.js +76 -76
- package/src/core/parser/plotly.config.js +10 -10
- package/src/core/parser/plotly.data.js +132 -132
- package/src/core/parser/plotly.layout.js +9 -9
- package/src/core/parser/plotly.violin.js +18 -18
- package/src/core/recharts.js +62 -62
- package/src/core/router/alias.js +49 -49
- package/src/core/router/jsonRouter.js +31 -31
- package/src/core/themes/modern.js +32 -32
- package/src/core/themes/themeSelector.js +33 -33
- package/src/core/visualify.js +47 -47
- package/src/core/widgets/circularProgress.js +23 -23
- package/src/core/widgets/controller.js +83 -83
- package/src/core/widgets/errorBoundary.js +36 -36
- package/src/core/widgets/footer.js +177 -177
- package/src/core/widgets/header.js +234 -234
- package/src/core/widgets/layout/Grid.js +31 -31
- package/src/core/widgets/layout.js +36 -36
- package/src/core/widgets/mapping.js +42 -42
- package/src/index.js +62 -62
- package/src/setupTests.js +5 -5
- package/docs/docs/CLI.md +0 -34
- package/docs/docs/Rechart/scatter.md +0 -298
- package/docs/docs/log.md +0 -9
- package/docs/docs/static/logo/favicon.ico +0 -0
- package/docs/docs/static/logo/logo_128x128.png +0 -0
- package/docs/docs/static/logo/logo_192x192.png +0 -0
- package/docs/docs/static/logo/logo_256x256.png +0 -0
- package/docs/docs/static/logo/logo_512x512.png +0 -0
- package/docs/docs/static/logo/logo_64x64.png +0 -0
- package/docs/docs/theme.md +0 -5
- /package/docs/{docs/Rechart → Rechart}/geo.md +0 -0
- /package/docs/{docs/Rechart → Rechart}/liquidfill.md +0 -0
- /package/docs/{docs/Rechart → Rechart}/polar.md +0 -0
- /package/docs/{docs/Rechart → Rechart}/sankey.md +0 -0
- /package/docs/{docs/Rechart/sunburst.md → Rechart/scatter.md} +0 -0
- /package/docs/{docs/Rechart/tree.md → Rechart/sunburst.md} +0 -0
- /package/docs/{docs/Rechart/wordcloud.md → Rechart/tree.md} +0 -0
- /package/docs/{docs/components/markdown.md → Rechart/wordcloud.md} +0 -0
- /package/docs/{docs/static → static}/_images/deploy-github-pages.png +0 -0
@@ -1,165 +1,165 @@
|
|
1
|
-
import React, { useEffect, useState } from 'react';
|
2
|
-
import ScatterBio from './ScatterBio';
|
3
|
-
import simplefetch from '../fetch/fetch';
|
4
|
-
import { useAppContext } from '../appContext';
|
5
|
-
|
6
|
-
const VisiumPlot = ({ props, style }) => {
|
7
|
-
// Declare states at the beginning
|
8
|
-
const { sharedData } = useAppContext();
|
9
|
-
const { debug } = props;
|
10
|
-
|
11
|
-
const [updatedProps, setUpdatedProps] = useState(props);
|
12
|
-
|
13
|
-
useEffect(() => {
|
14
|
-
const { metaval } = props;
|
15
|
-
|
16
|
-
let section = sharedData[metaval] ?? [];
|
17
|
-
let VisiumProps = {
|
18
|
-
...props,
|
19
|
-
config: {
|
20
|
-
...props.config,
|
21
|
-
//visium_cell_fraction: "BC",
|
22
|
-
visualMap: {
|
23
|
-
calculable: true,
|
24
|
-
top: 'bottom',
|
25
|
-
orient: 'horizontal',
|
26
|
-
right: 'center',
|
27
|
-
},
|
28
|
-
zcolor: ['#FFFF80', '#FFA500', '#FF0000'],
|
29
|
-
toolbox: {
|
30
|
-
saveAsImage: {
|
31
|
-
show: true,
|
32
|
-
},
|
33
|
-
},
|
34
|
-
//dataZoom: "inside", // "inside", "slider", 'both'
|
35
|
-
dotsize: '2',
|
36
|
-
labels: {
|
37
|
-
z: ['log2\n(tpm+1)', ''],
|
38
|
-
},
|
39
|
-
|
40
|
-
xAxis: {
|
41
|
-
show: false,
|
42
|
-
},
|
43
|
-
yAxis: {
|
44
|
-
show: false,
|
45
|
-
},
|
46
|
-
legend: false,
|
47
|
-
formatter: (params) => {
|
48
|
-
let resultHtml = '';
|
49
|
-
for (const [key, value] of Object.entries(params.data)) {
|
50
|
-
if (key === 'Expression') {
|
51
|
-
continue;
|
52
|
-
}
|
53
|
-
if (value > 0.5) {
|
54
|
-
// Only show the cell type with likelihood >= 0.5
|
55
|
-
resultHtml += `<br>${key}: ${value.toFixed(3)}`;
|
56
|
-
}
|
57
|
-
}
|
58
|
-
return `
|
59
|
-
<div style="text-align: center;">
|
60
|
-
${params.name}
|
61
|
-
<br> Cell2Location Cell Type Likelihood
|
62
|
-
<br> (Likelihood >= 0.5)
|
63
|
-
${resultHtml}
|
64
|
-
</div>
|
65
|
-
`;
|
66
|
-
},
|
67
|
-
grid: {
|
68
|
-
top: '15%',
|
69
|
-
bottom: '12%',
|
70
|
-
left: '5%',
|
71
|
-
right: '10%',
|
72
|
-
},
|
73
|
-
},
|
74
|
-
};
|
75
|
-
|
76
|
-
const { cellval } = props;
|
77
|
-
|
78
|
-
if (
|
79
|
-
cellval &&
|
80
|
-
sharedData[cellval] !== undefined &&
|
81
|
-
sharedData[cellval].length > 0
|
82
|
-
) {
|
83
|
-
let selected_celltype = sharedData[cellval][0];
|
84
|
-
if (
|
85
|
-
selected_celltype === 'Default' ||
|
86
|
-
selected_celltype === 'None' ||
|
87
|
-
selected_celltype === 'NA' ||
|
88
|
-
selected_celltype === 'N/A' ||
|
89
|
-
selected_celltype === 'Unknown' ||
|
90
|
-
selected_celltype === 'Unassigned' ||
|
91
|
-
selected_celltype === 'All'
|
92
|
-
)
|
93
|
-
VisiumProps.config.visium_cell_fraction = null;
|
94
|
-
else {
|
95
|
-
VisiumProps.config.visium_cell_fraction =
|
96
|
-
sharedData[cellval][0];
|
97
|
-
VisiumProps.config.visualMap.text = [
|
98
|
-
'Likelihood of being a ' + sharedData[cellval][0],
|
99
|
-
'',
|
100
|
-
];
|
101
|
-
}
|
102
|
-
}
|
103
|
-
|
104
|
-
function BufferImage(imageBuffer) {
|
105
|
-
// Create a Blob object from the binary data
|
106
|
-
const blob = new Blob([new Uint8Array(imageBuffer)], {
|
107
|
-
type: 'image/png',
|
108
|
-
});
|
109
|
-
// Create a URL from the Blob
|
110
|
-
const dataURL = URL.createObjectURL(blob);
|
111
|
-
// Create the Image object
|
112
|
-
const imageDom = new Image();
|
113
|
-
imageDom.onload = () => {
|
114
|
-
// Wait until the image is loaded
|
115
|
-
// Set the background properties
|
116
|
-
VisiumProps.config.backgroundColor = {
|
117
|
-
image: dataURL,
|
118
|
-
repeat: 'no-repeat',
|
119
|
-
};
|
120
|
-
|
121
|
-
//console.log("VisiumProps", VisiumProps);
|
122
|
-
// Update the state with the loaded image
|
123
|
-
setUpdatedProps(VisiumProps);
|
124
|
-
};
|
125
|
-
imageDom.src = dataURL;
|
126
|
-
}
|
127
|
-
|
128
|
-
const fetchImage = async () => {
|
129
|
-
const imageBuffer = await simplefetch(image + section, {
|
130
|
-
type: 'image',
|
131
|
-
debug: debug,
|
132
|
-
});
|
133
|
-
BufferImage(imageBuffer.data);
|
134
|
-
};
|
135
|
-
|
136
|
-
const { image } = props;
|
137
|
-
if (section.length > 0) {
|
138
|
-
section = section[0];
|
139
|
-
VisiumProps.config.title = {
|
140
|
-
text: 'Section ' + section,
|
141
|
-
left: 'center',
|
142
|
-
top: 'top',
|
143
|
-
textStyle: {
|
144
|
-
fontSize: 25,
|
145
|
-
fontWeight: 'bold',
|
146
|
-
color: 'black',
|
147
|
-
},
|
148
|
-
};
|
149
|
-
fetchImage();
|
150
|
-
}
|
151
|
-
}, [props, sharedData, debug]);
|
152
|
-
|
153
|
-
return (
|
154
|
-
<>
|
155
|
-
<ScatterBio
|
156
|
-
key={updatedProps.id + '.inherent'}
|
157
|
-
props={updatedProps}
|
158
|
-
style={style}
|
159
|
-
reset={null}
|
160
|
-
/>
|
161
|
-
</>
|
162
|
-
);
|
163
|
-
};
|
164
|
-
|
165
|
-
export default VisiumPlot;
|
1
|
+
import React, { useEffect, useState } from 'react';
|
2
|
+
import ScatterBio from './ScatterBio';
|
3
|
+
import simplefetch from '../fetch/fetch';
|
4
|
+
import { useAppContext } from '../appContext';
|
5
|
+
|
6
|
+
const VisiumPlot = ({ props, style }) => {
|
7
|
+
// Declare states at the beginning
|
8
|
+
const { sharedData } = useAppContext();
|
9
|
+
const { debug } = props;
|
10
|
+
|
11
|
+
const [updatedProps, setUpdatedProps] = useState(props);
|
12
|
+
|
13
|
+
useEffect(() => {
|
14
|
+
const { metaval } = props;
|
15
|
+
|
16
|
+
let section = sharedData[metaval] ?? [];
|
17
|
+
let VisiumProps = {
|
18
|
+
...props,
|
19
|
+
config: {
|
20
|
+
...props.config,
|
21
|
+
//visium_cell_fraction: "BC",
|
22
|
+
visualMap: {
|
23
|
+
calculable: true,
|
24
|
+
top: 'bottom',
|
25
|
+
orient: 'horizontal',
|
26
|
+
right: 'center',
|
27
|
+
},
|
28
|
+
zcolor: ['#FFFF80', '#FFA500', '#FF0000'],
|
29
|
+
toolbox: {
|
30
|
+
saveAsImage: {
|
31
|
+
show: true,
|
32
|
+
},
|
33
|
+
},
|
34
|
+
//dataZoom: "inside", // "inside", "slider", 'both'
|
35
|
+
dotsize: '2',
|
36
|
+
labels: {
|
37
|
+
z: ['log2\n(tpm+1)', ''],
|
38
|
+
},
|
39
|
+
|
40
|
+
xAxis: {
|
41
|
+
show: false,
|
42
|
+
},
|
43
|
+
yAxis: {
|
44
|
+
show: false,
|
45
|
+
},
|
46
|
+
legend: false,
|
47
|
+
formatter: (params) => {
|
48
|
+
let resultHtml = '';
|
49
|
+
for (const [key, value] of Object.entries(params.data)) {
|
50
|
+
if (key === 'Expression') {
|
51
|
+
continue;
|
52
|
+
}
|
53
|
+
if (value > 0.5) {
|
54
|
+
// Only show the cell type with likelihood >= 0.5
|
55
|
+
resultHtml += `<br>${key}: ${value.toFixed(3)}`;
|
56
|
+
}
|
57
|
+
}
|
58
|
+
return `
|
59
|
+
<div style="text-align: center;">
|
60
|
+
${params.name}
|
61
|
+
<br> Cell2Location Cell Type Likelihood
|
62
|
+
<br> (Likelihood >= 0.5)
|
63
|
+
${resultHtml}
|
64
|
+
</div>
|
65
|
+
`;
|
66
|
+
},
|
67
|
+
grid: {
|
68
|
+
top: '15%',
|
69
|
+
bottom: '12%',
|
70
|
+
left: '5%',
|
71
|
+
right: '10%',
|
72
|
+
},
|
73
|
+
},
|
74
|
+
};
|
75
|
+
|
76
|
+
const { cellval } = props;
|
77
|
+
|
78
|
+
if (
|
79
|
+
cellval &&
|
80
|
+
sharedData[cellval] !== undefined &&
|
81
|
+
sharedData[cellval].length > 0
|
82
|
+
) {
|
83
|
+
let selected_celltype = sharedData[cellval][0];
|
84
|
+
if (
|
85
|
+
selected_celltype === 'Default' ||
|
86
|
+
selected_celltype === 'None' ||
|
87
|
+
selected_celltype === 'NA' ||
|
88
|
+
selected_celltype === 'N/A' ||
|
89
|
+
selected_celltype === 'Unknown' ||
|
90
|
+
selected_celltype === 'Unassigned' ||
|
91
|
+
selected_celltype === 'All'
|
92
|
+
)
|
93
|
+
VisiumProps.config.visium_cell_fraction = null;
|
94
|
+
else {
|
95
|
+
VisiumProps.config.visium_cell_fraction =
|
96
|
+
sharedData[cellval][0];
|
97
|
+
VisiumProps.config.visualMap.text = [
|
98
|
+
'Likelihood of being a ' + sharedData[cellval][0],
|
99
|
+
'',
|
100
|
+
];
|
101
|
+
}
|
102
|
+
}
|
103
|
+
|
104
|
+
function BufferImage(imageBuffer) {
|
105
|
+
// Create a Blob object from the binary data
|
106
|
+
const blob = new Blob([new Uint8Array(imageBuffer)], {
|
107
|
+
type: 'image/png',
|
108
|
+
});
|
109
|
+
// Create a URL from the Blob
|
110
|
+
const dataURL = URL.createObjectURL(blob);
|
111
|
+
// Create the Image object
|
112
|
+
const imageDom = new Image();
|
113
|
+
imageDom.onload = () => {
|
114
|
+
// Wait until the image is loaded
|
115
|
+
// Set the background properties
|
116
|
+
VisiumProps.config.backgroundColor = {
|
117
|
+
image: dataURL,
|
118
|
+
repeat: 'no-repeat',
|
119
|
+
};
|
120
|
+
|
121
|
+
//console.log("VisiumProps", VisiumProps);
|
122
|
+
// Update the state with the loaded image
|
123
|
+
setUpdatedProps(VisiumProps);
|
124
|
+
};
|
125
|
+
imageDom.src = dataURL;
|
126
|
+
}
|
127
|
+
|
128
|
+
const fetchImage = async () => {
|
129
|
+
const imageBuffer = await simplefetch(image + section, {
|
130
|
+
type: 'image',
|
131
|
+
debug: debug,
|
132
|
+
});
|
133
|
+
BufferImage(imageBuffer.data);
|
134
|
+
};
|
135
|
+
|
136
|
+
const { image } = props;
|
137
|
+
if (section.length > 0) {
|
138
|
+
section = section[0];
|
139
|
+
VisiumProps.config.title = {
|
140
|
+
text: 'Section ' + section,
|
141
|
+
left: 'center',
|
142
|
+
top: 'top',
|
143
|
+
textStyle: {
|
144
|
+
fontSize: 25,
|
145
|
+
fontWeight: 'bold',
|
146
|
+
color: 'black',
|
147
|
+
},
|
148
|
+
};
|
149
|
+
fetchImage();
|
150
|
+
}
|
151
|
+
}, [props, sharedData, debug]);
|
152
|
+
|
153
|
+
return (
|
154
|
+
<>
|
155
|
+
<ScatterBio
|
156
|
+
key={updatedProps.id + '.inherent'}
|
157
|
+
props={updatedProps}
|
158
|
+
style={style}
|
159
|
+
reset={null}
|
160
|
+
/>
|
161
|
+
</>
|
162
|
+
);
|
163
|
+
};
|
164
|
+
|
165
|
+
export default VisiumPlot;
|
@@ -1,42 +1,42 @@
|
|
1
|
-
/*
|
2
|
-
* @Author : Lihao leolihao@arizona.edu
|
3
|
-
* @Date : 2023-12-25 21:57:39
|
4
|
-
* @FilePath : /visualify.js/src/core/components/browser.js
|
5
|
-
* @Description :
|
6
|
-
* Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
|
7
|
-
*/
|
8
|
-
import React, { useEffect, useState } from 'react';
|
9
|
-
|
10
|
-
function Browser({ props, style }) {
|
11
|
-
const { src, style: _style, title, width, height } = props;
|
12
|
-
const [error, setError] = useState(null);
|
13
|
-
|
14
|
-
useEffect(() => {
|
15
|
-
// Clear any previous error when the src changes
|
16
|
-
setError(null);
|
17
|
-
}, [src]);
|
18
|
-
|
19
|
-
return (
|
20
|
-
<>
|
21
|
-
<iframe
|
22
|
-
src={src}
|
23
|
-
title={title}
|
24
|
-
width={width}
|
25
|
-
height={height}
|
26
|
-
style={{ ...style }}
|
27
|
-
onError={() => {
|
28
|
-
setError('Error loading content. Please check the URL.');
|
29
|
-
}}
|
30
|
-
/>
|
31
|
-
{error && (
|
32
|
-
<div
|
33
|
-
className='iframe-error'
|
34
|
-
style={{ ...style, ..._style }}>
|
35
|
-
{error}
|
36
|
-
</div>
|
37
|
-
)}
|
38
|
-
</>
|
39
|
-
);
|
40
|
-
}
|
41
|
-
|
42
|
-
export default Browser;
|
1
|
+
/*
|
2
|
+
* @Author : Lihao leolihao@arizona.edu
|
3
|
+
* @Date : 2023-12-25 21:57:39
|
4
|
+
* @FilePath : /visualify.js/src/core/components/browser.js
|
5
|
+
* @Description :
|
6
|
+
* Copyright (c) 2023 by Lihao (leolihao@arizona.edu), All Rights Reserved.
|
7
|
+
*/
|
8
|
+
import React, { useEffect, useState } from 'react';
|
9
|
+
|
10
|
+
function Browser({ props, style }) {
|
11
|
+
const { src, style: _style, title, width, height } = props;
|
12
|
+
const [error, setError] = useState(null);
|
13
|
+
|
14
|
+
useEffect(() => {
|
15
|
+
// Clear any previous error when the src changes
|
16
|
+
setError(null);
|
17
|
+
}, [src]);
|
18
|
+
|
19
|
+
return (
|
20
|
+
<>
|
21
|
+
<iframe
|
22
|
+
src={src}
|
23
|
+
title={title}
|
24
|
+
width={width}
|
25
|
+
height={height}
|
26
|
+
style={{ ...style }}
|
27
|
+
onError={() => {
|
28
|
+
setError('Error loading content. Please check the URL.');
|
29
|
+
}}
|
30
|
+
/>
|
31
|
+
{error && (
|
32
|
+
<div
|
33
|
+
className='iframe-error'
|
34
|
+
style={{ ...style, ..._style }}>
|
35
|
+
{error}
|
36
|
+
</div>
|
37
|
+
)}
|
38
|
+
</>
|
39
|
+
);
|
40
|
+
}
|
41
|
+
|
42
|
+
export default Browser;
|