React native drag and drop - reactjs

I'm trying to implement drag and drop in a React Native application.
Has anyone out there used this ? Somehow I'm not able to drag the text. There are not enough steps to use the npm module.
After debugging for some time I found that onLayout & onLongPress are undefined, can anyone help me on this ?

Assuming you're new to React Native (as am I, kind of), and you don't have an example of your code, there might be a few things going on. (and there is a high chance you already know all of these things).
Did you follow this example? Here they set onLayout and onLongPress as the props of the DraggableThing component. Next they call the component with functions (onDragItemLayout, startDragHandler) bound to these properties. These functions are supplied by importing the createDropZone, did you import everything?
If you did, importing third-party components is kind of a hassle, because most of the times you're required to do some things in xCode. Not sure if that's also the case right now, but it might be something to look into.
Also my advice would be to take a look at the module supplied in the answer above.

This is a simple React drag and drop.
class Square extends React.Component {
constructor() {
super();
this.state = {
posx: 10,
posy: 10,
};
this.setDrag = this.setDrag.bind(this);
this.startDrag = this.startDrag.bind(this);
this.stopDrag = this.stopDrag.bind(this);
}
componentDidMount() {
this.sq.addEventListener('mousedown', this.setDrag);
}
startDrag(e) {
this.setState({
posx: parseInt(e.clientX - this.startPosX, 10),
posy: parseInt(e.clientY - this.startPosY, 10),
});
this.startPosX = e.clientX - this.state.posx;
this.startPosY = e.clientY - this.state.posy;
}
stopDrag() {
document.documentElement.removeEventListener('mousemove', this.startDrag);
document.documentElement.removeEventListener('mouseup', this.stopDrag);
this.sq.addEventListener('mousedown', this.setDrag);
}
setDrag(e) {
this.sq.removeEventListener('mousedown', this.setDrag);
this.startPosX = e.clientX - this.state.posx;
this.startPosY = e.clientY - this.state.posy;
document.documentElement.addEventListener('mousemove', this.startDrag);
document.documentElement.addEventListener('mouseup', this.stopDrag);
}
render() {
return (
<div
className='square'
style={{
left: this.state.posx,
top: this.state.posy,
}}
ref={(sq) => { this.sq = sq; }}
>
{this.state.posx}
</div>
);
}
}
ReactDOM.render(
<Square />,
document.getElementById('app')
);
.square {
position: absolute;
width: 100px;
height: 100px;
background: #900;
border: 1px solid #333;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>

Related

Shorter way to use SCSS #exported classNames in React (Next.js + css-modules)

I have a set of semantic color classes in SCSS, which should be applied to components based on their props. I'm using React + Next.js + css-modules.
What I Want:
The current code I wrote below works correctly, but I want a simpler approach... declaring a bunch of classNames for every component to #extend something else is overkill! I want to write the extension directly in jsx part. Is there a better (more dynamic) way to do this? maybe inline extends?
Not a valid code, but I'm looking for something like this:
export default function Component({ status }) {
return (
<div style={#extend %{status}}>
...
</div>
)
}
Code
This is the semantics file. I import it inside other scss files to extend the classes:
/* _semantics.scss */
%warning {
background: orange;
color: red;
}
%error {
background: red;
color: black;
}
...
Example Component
/* component.module.scss */
#use "semantics" as *;
.warning {
#extend %warning;
}
.error {
#extend %error;
}
.success {
#extend %success;
}
// component.jsx
import css from "./component.module.scss"
export default function Component({ status }) {
return (
<div className={css[status]}>
...
</div>
)
}
// index.jsx
<Component status="warning">...</Component>
Notes
I am looking for an alternative way, so:
Using a package is fine
Using #include (mixins) instead of #extend is fine
Using .semantic-class instead of %semantic-class is fine
you can use global css to achieve this purpose

how to use react-watermark-component library inside the code to get the watermark over an image- ReactJs

I want to add a watermark over an image file. I'm using the "https://libraries.io/npm/react-watermark-component" npm library to achieve the result. so far I have:
render() {
const waterMarkOptions = {
chunkWidth: 200,
chunkHeight: 60,
textAlign: "left",
textBaseline: "bottom",
globalAlpha: 0.17,
font: "14px Microsoft Yahei",
rotateAngle: -0.26,
fillStyle: "#666"
};
<ReactWaterMark
waterMarkText="Confidenatiality"
openSecurityDefense
options={waterMarkOptions}>
<MyComponent>
.
.
.
</MyComponent>
</ReactWaterMark>
}
But doing this it does nothing, it does not add any watermark to the component.
I also tried the watermar.js - https://github.com/brianium/watermarkjs
but I'm sure of its usage inside a ReactComponent.
This is the usage:
const options = {
init(img) {
img.crossOrigin = 'anonymous'
}
};
watermark(['http://host.com/photo.jpg', 'http://host.com/logo.png'], options)
.image(watermark.image.lowerRight(0.5))
.then(img => document.getElementById('container').appendChild(img));
Mycomponent:
export default class Dialog extends React.Component {
render() {
return <div>
//where should I insert the watermark script?
</div>
}
}
Just FYI, my component is a dialog box and I have text/images inside.
Note: For testing purpose I have added water mark to the entire component, however I;d want to add water precisely on the image. But before that I want to see if I''m making use of component correctly.
any idea?

React-diagrams invisible

Following the installation guide in projectstorm/react-diagrams docs, I have trouble with the diagram not rendering properly. Inspecting the page reveals the positions of the nodes - but they are invisible. Using sass, I have imported into app.scss
#import "~storm-react-diagrams/src/sass/main";
I have also tried using the raw minified css with no improvement.
I still assume this is an error on my end, possibly I create the engine in the wrong place? I have a engineReducer to provide the default engine.
import * as SRD from "storm-react-diagrams";
//1) setup the diagram engine
var engine = new SRD.DiagramEngine();
engine.installDefaultFactories();
//2) setup the diagram model
var model = new SRD.DiagramModel();
//3-A) create a default node
var node1 = new SRD.DefaultNodeModel("Node 1", "rgb(0,192,255)");
let port1 = node1.addOutPort("Out");
node1.setPosition(100, 100);
//3-B) create another default node
var node2 = new SRD.DefaultNodeModel("Node 2", "rgb(192,255,0)");
let port2 = node2.addInPort("In");
node2.setPosition(400, 100);
// link the ports
let link1 = port1.link(port2);
link1.addLabel("Hello World!");
//4) add the models to the root graph
model.addAll(node1, node2, link1);
//5) load model into engine
engine.setDiagramModel(model);
const initialEngine = engine;
export default function (state = engine, action) {
return state;
}
Then, my main component looks like this:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import * as SRD from "storm-react-diagrams"
import {connect} from 'react-redux';
class Main extends Component {
render() {
console.log(this.props.engine); // Looks good!
return (
<div className="app">
<SRD.DiagramWidget className="srd-demo-canvas" diagramEngine={this.props.engine} />
</div>
);
}
}
function mapStateToProps(state) {
return { engine: state.engine };
}
export default connect(mapStateToProps)(Main)
Quite honestly I dont understand the docs reference to
In your library code
that is, where should I initialize the engine? What else am I missing?
You need to set a explicit height for the widget. Something like:
.srd-demo-canvas {
height: 100vh;
}
.srd-demo-canvas {
height: 100vh;
background-color: rgb(60,60,60)
}
Setting the background-color in addition to the height helped me see the links against the white background that Chrome gave me by default.
If you want the grid that the demos show, then install sass and:
.srd-demo-canvas{
height: 100%;
min-height: 300px;
background-color: rgb(60,60,60) !important;
$color: rgba(white, .05);
background-image:
linear-gradient(0deg,
transparent 24%,
$color 25%,
$color 26%,
transparent 27%,
transparent 74%,
$color 75%,
$color 76%,
transparent 77%,
transparent),
linear-gradient(90deg,
transparent 24%,
$color 25%,
$color 26%,
transparent 27%,
transparent 74%,
$color 75%,
$color 76%,
transparent 77%,
transparent);
background-size:50px 50px;
.pointui{
fill: rgba(white,0.5);
}
}
I tried following the suggested fixes but nothing worked for me.
Here's what really fixed the issue for both the nodes and the elements not showing properly.
I removed the importing of the storm-react-diagrams/dist/style.min.css
and instead, I created a custom CSS file which is the above file with the following modifications (You can find it under "node_modules/storm-react-diagrams/dist/" style.min.css):
.srd-diagram{position:unset;flex-grow:1;display:flex;cursor:move;overflow:visible}
(position to unset and overflow to visible)
.srd-link-layer{position:unset; ...}
(position to unset)
In general , the wrapper element (div for example) should have those css properties.
display:grid;
height: 100vh;
min-height: 100%;
width: 100vw;
Hello guys I have decided to start my own flowchart open project with ReactJs, but if you need, you can adapt it to pure javascript, please feel free to contribute.
https://github.com/lmoraobando/lmDiagram

get index value from react loop and pass it to css

I created react component that is taking an array and stacking all the progress bars into one.
const ProgressBar = (props, {...customProps}) => {
const GroupProgressBar = [];
props.groups.map((group, i) => {
const widthValue = (group.value / group.max) * 100;
GroupProgressBar.push
(<div style={{width: `${widthValue}%`}}
key = {i}
className={`well-background--${group.concept}
animation
terra-ProgressGroup--progress
terra-ProgressBar--${props.heightSize}`}>
</div>);
})
return <div className='terra-ProgressGroup'> {GroupProgressBar} </div>
}
CSS (classes below i want to convert to single class):
....
.well-background--concept1 {
animation-delay: 1s;
z-index: -1;
}
.well-background--concept2 {
animation-delay: 2s;
z-index: -2;
}
.well-background--concept3 {
animation-delay: 3s;
z-index: -3;
}
I tried to convert these classes into one but have no luck
:root {
--concept-code: key;
--concept-code2: key;
}
.animation {
animation-delay: var(--concept-code)s;
z-index: var(--concept-code2);
}
Basically i dont want keep adding those similar classes so i am trying to create a single class and pass those numbers from react component. probably using key = {i}
How can i achieve that?
Why even bother with CSS for this case? The point of CSS is that the styles cascade and have hierarchy. If the style applies only to a specific React component, then it's best to render the appropriate styles directly.
const ProgressBar = (props, {...customProps}) => {
const GroupProgressBar = [];
props.groups.map((group, i) => {
const widthValue = (group.value / group.max) * 100;
GroupProgressBar.push
(<div
style={{
width: `${widthValue}%`,
animationDelay: /* based on the concept number */,
zIndex: /* based on the concept number */
}}
key = {i}
className={`well-background--${group.concept}
animation
terra-ProgressGroup--progress
terra-ProgressBar--${props.heightSize}`}>
</div>);
})
return <div className='terra-ProgressGroup'> {GroupProgressBar} </div>
}
Note that I'm not sure how you can generate the appropriate number for your style because I don't know your data structure. But that would be trivial enough. The important part is just rendering the style in the component instead of CSS.
There's not really a great way to dynamically inject CSS class style definitions into the page with React. And even so, that would be vastly over-engineering a solution for this problem. Better to just create lots of .well-background class definitions in the CSS manually, as many as you think you'll need (10? 20? How many will there really be?).

Am unable to increase Height of Codemirror React Component

In my React application, I am using 'Editor.jsx component (which is just a wrapper around code-mirror, in case I need to provide frills around the actual CodeMirror-view).
The in which the rendered component from attached file is added to, has height of 100% and other components similar to CodeMirror do use that full height.
The CodeMirror component however only shows 15 lines (and i have to scroll to get to the ones below).
The code is very similar to the sample from github. The height property in getInitialState() also has no effect (neither does the containing ).
import React from 'react';
var CodeMirror = require('react-codemirror');
// fishing this 'require' out has caused severe headache and cost time.
// IF not included, default bootstrap style used. must override it with this.
// but for react-codemirror component we need this one!!!
// REF http://dorianpula.ca/2015/10/07/adding-a-code-editor-to-rookeries/
require("codemirror/lib/codemirror.css");
require('codemirror/mode/javascript/javascript');
require('codemirror/mode/python/python');
var DFLTS = {
javascript: 'var component = {\n\tname: "react-codemirror",\n\tauthor: "Jed Watson",\n\tforUseBy: "KB"}',
python: 'print "hello python world"'
}
export default React.createClass ({
localOnCodeChange(newCode) {
this.props.onCodeChange(newCode)
},
getInitialState() {
return {
code: DFLTS.javascript,
readOnly: false,
mode: 'javascript',
height:"100%",
viewportMargin: "Infinity"
};
},
componentDidMount() {
CodeMirror.setSize("100%", 1000);
},
changeMode(e) {
// add python later.
// no-op
},
toggleRreadOnly() {
this.setState({
readOnly: !this.state.readOnly
}, () => this.refs.editor.focus());
},
interact(cm) {
console.log(cm.getValue());
},
render() {
var options = {
lineNumbers: true,
readOnly: this.state.readOnly,
mode: this.state.mode
};
return (
<CodeMirror ref="editor" value={this.props.code} onChange={this.props.onCodeChange} options={options} interact={this.interact}/>
)
}
});
Any pointers, greatly appreciated.
The .CodeMirror class in this library appears to have a hard-coded height: 300px in it and there's an unanswered question in their issues about being able to set the height. If you put .CodeMirror { min-height: 100% } in your CSS that might do the trick.
Alternatively pass a className to <CodeMirror> (it will get added to the classes) that sets a min height, or a height with !important, or just greater specificity.
(Tsk tsk to components that you have to fight with :))
if you need to dynamically change the height, or simply dont want to use css you can use ref
const codemirrorRef = React.useRef();
React.useEffect(() => {
const current = codemirrorRef.current.editor.display.wrapper.style.height = "1000px";
});
<CodeMirror
[...]
ref={codemirrorRef}
/>
codemirrorRef.current.editor.display.wrapper contains the div element. From there you can do anything you would do if you did document.getElementById('#id')
I was able to get the height to override by adding an addition to the existing CodeMirror class in my CSS file as follows:
.CodeMirror {
height: 100% !important
}
it only applied the change after adding !important to force it to override the existing class which is hard coded to 300 pixels.

Resources