I am aiming to use a Vanilla JavaScript package in a more sophisticated React app to build additional logic around the JavaScript package.
The JavaScript library is LabelStudio and docs can be found here: https://github.com/heartexlabs/label-studio-frontend
However, when I try to import the LabelStudio I get an error saying Module not found: Can't resolve 'label-studio'
, as described here https://github.com/heartexlabs/label-studio-frontend/issues/55
Since my understanding of frontend code is limited, I am not sure whether this is something the developers did not expected users to do and just wanted them to use the entire library and customized instead of using the library as a component. My idea was to use the library as in the vanilla javascript example here:
<!-- Include Label Studio stylesheet -->
<link href="https://unpkg.com/[email protected]/build/static/css/main.0a1ce8ac.css" rel="stylesheet">
<!-- Create the Label Studio container -->
<div id="label-studio"></div>
<!-- Include the Label Studio library -->
<script src="https://unpkg.com/[email protected]/build/static/js/main.3ee35cc9.js"></script>
<!-- Initialize Label Studio -->
<script>
var labelStudio = new LabelStudio('label-studio', {
config: `
<View>
<Image name="img" value="$image"></Image>
<RectangleLabels name="tag" toName="img">
<Label value="Hello"></Label>
<Label value="World"></Label>
</RectangleLabels>
</View>
`,
interfaces: [
"panel",
"update",
"controls",
"side-column",
"completions:menu",
"completions:add-new",
"completions:delete",
"predictions:menu",
],
user: {
pk: 1,
firstName: "James",
lastName: "Dean"
},
task: {
completions: [],
predictions: [],
id: 1,
data: {
image: "https://htx-misc.s3.amazonaws.com/opensource/label-studio/examples/images/nick-owuor-astro-nic-visuals-wDifg5xc9Z4-unsplash.jpg"
}
},
onLabelStudioLoad: function(LS) {
var c = LS.completionStore.addCompletion({
userGenerate: true
});
LS.completionStore.selectCompletion(c.id);
}
});
</script>
How can I make use of the above code in a React Component to facilitate dynamic data loading and use of state to customize the functions?
I don't have a solution making the npm module label-studio
to work. I tried importing the dist file instead, but it errors
Expected an assignment or function call and instead saw an expression
So here's a workaround until the maintainers address this.
Copy the JS file from build/static/js, then place it in a script in the public folder on index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using create-react-app" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script src="%Your_Path_To_Label-Studio%/main.js"></script>
</body>
</html>
The script file defines a global function variable, so you can access it in React by using the window object. The useEffect hook is to make sure the initialization is only run once.
import React, { useEffect, useRef } from "react";
function App() {
const LabelStudio = window.LabelStudio; // label-studio script stores the api globally, similar to how jQuery does
const myLabelStudioRef = useRef(null); // store it and then pass it other components
useEffect(() => {
myLabelStudioRef.current = new LabelStudio("label-studio", {
config: `
<View>
<Image name="img" value="$image"></Image>
<RectangleLabels name="tag" toName="img">
<Label value="Hello"></Label>
<Label value="World"></Label>
</RectangleLabels>
</View>
`,
interfaces: [
"panel",
"update",
"controls",
"side-column",
"completions:menu",
"completions:add-new",
"completions:delete",
"predictions:menu",
],
user: {
pk: 1,
firstName: "James",
lastName: "Dean",
},
task: {
completions: [],
predictions: [],
id: 1,
data: {
image:
"https://htx-misc.s3.amazonaws.com/opensource/label-studio/examples/images/nick-owuor-astro-nic-visuals-wDifg5xc9Z4-unsplash.jpg",
},
},
onLabelStudioLoad: function (LS) {
var c = LS.completionStore.addCompletion({
userGenerate: true,
});
LS.completionStore.selectCompletion(c.id);
},
});
}, []);
return (
<div className="App">
{/* Use Label Studio container */}
<div id="label-studio"></div>
</div>
);
}
export default App;
As far as storing the new instance of LabelStudio, there's many ways to go about it. You can store it as variable on the root component using either useState
or useRef
hooks and then pass it to child components. If you want to avoid manually passing variable down the component tree, then you need a state manager such as React Context or Redux.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With