I am new into Grafana. I created a custom plugin on which I have a Button. The project compiles without issues, and the button appears on the panel, but no click event is handled
Please find below the source code
import React from ‘react’;
import { PanelProps } from ‘#grafana/data’;
import { SimpleOptions } from ‘types’;
import { css, cx } from ‘#emotion/css’;
import { Button, useStyles2, useTheme2 } from ‘#grafana/ui’;
interface Props extends PanelProps {}
const getStyles = () => {
return {
wrapper: css font-family: Open Sans; position: relative; ,
svg: css position: absolute; top: 0; left: 0; ,
textBox: css position: absolute; bottom: 0; left: 0; padding: 10px; ,
hover:css background-color: rgba(255, 0, 0, 1); ,
active:css background-color: rgba(255, 255, 0, 1); ,
};
};
export const SimplePanel: React.FC = ({ options, data, width, height }) => {
const theme = useTheme2();
const styles = useStyles2(getStyles);
return (
<div
className={cx(
styles.wrapper,
css width: ${width}px; height: ${height}px;
)}
>
<svg
className={styles.svg}
width={width}
height={height}
xmlns=“SVG namespace”
xmlnsXlink=“XLink namespace”
viewBox={-${width / 2} -${height / 2} ${width} ${height}}
>
<circle style={{ fill: theme.colors.primary.main }} r={100} />
<div className={styles.textBox}>
{options.showSeriesCount && <div>Number of series: {data.series.length}</div>}
<div>Text option value: {options.text}</div>
</div>
<Button onClick={()=>console.log("test")}>TestButton</Button>
</div>
);
};
I also changed in the defaults.ini the disable_sanitize_html = true but the problem didn’t get solved.
Please can you advice what to do next.
I set the disable_sanitize_html=true but didn't work.
Related
I am trying to build a react component with a large fixed div and a navbar below. Initially, the div should remain fixed at the top left and scroll through a number of slides as the user scrolls, before its display property reverts to absolute and it scrolls out of view. Meanwhile, the nav's position becomes sticky and scrolls to the top of the window where it remains.
I've managed to build something hacky using react-intersection-observer and a number of hidden 'ghost' elements which allow the slides to cycle between opacity 0 or 1, but the outcome is not great and I feel there must be an easier way to achieve this effect. In particular it is problematic having to account for the page position when the main component becomes absolute positioned and requires a 'top' value.
Any advice is appreciated thanks. Sample code is below:
import * as React from 'react';
import { useInView } from 'react-intersection-observer';
import styled from 'styled-components';
const OuterContainer = styled.div`
height: 500vh;
`;
const Card = styled.div`
box-sizing: border-box;
position: fixed;
top: 0;
width: 100%;
height:64vh;
transition: 1s;
z-index: 5;
&.hidden {
opacity: 0;
}
&.show {
opacity: 1;
}
&.border {
position: absolute;
top: 0;
}
`;
const AltCard = styled(Card)`
position: static;
`;
const CardContainer = styled.div`
height: 64vh;
`;
const FirstCard = styled(Card)`
opacity: 1;
`;
const CardGhost = styled.div`
height:64vh;
`;
const LastGhost = styled.div`
box-sizing: border-box;
`;
const GhostContainer = styled.div`
width: 100%;
position: absolute;
top: 0;
`;
const MainContainer = styled.div`
position: fixed;
width: 100%;
top: 0;
&.moving {
position: absolute;
top: 156.5vh;
}
`;
const HeaderBar = styled.div`
top: 64vh;
display: flex;
align-items: center;
justify-content: center;
flex: 1;
height: 8rem;
background-color: #44ff44;
`;
export default function IntroSection() {
const options = { threshold: 0.66 };
const [ref0, visible0] = useInView({ threshold: 0 });
const [ref1, visible1] = useInView(options);
const [ref2, visible2] = useInView(options);
const [ref3, visible3] = useInView(options);
const [ref4, visible4] = useInView({ threshold: 0.33 });
return (
<>
<OuterContainer>
<GhostContainer>
<CardGhost ref={ref0} />
<CardGhost ref={ref1} />
<CardGhost ref={ref2} />
<CardGhost ref={ref3} />
<LastGhost ref={ref4} />
</GhostContainer>
<CardContainer>
<FirstCard
className={visible0 ? 'show' : 'hidden'}
style={{ backgroundColor: 'lightBlue' }}
/>
<Card
className={visible1 ? 'show' : 'hidden'}
style={{ backgroundColor: 'lightGreen' }}
/>
<Card
className={visible2 ? 'show' : 'hidden'}
style={{ backgroundColor: 'lightYellow' }}
/>
</CardContainer>
</OuterContainer>
<MainContainer
className={visible4 && 'moving'}
>
<AltCard
className={visible3 ? 'show' : 'hidden'}
style={{ backgroundColor: '#ffBBFF' }}
/>
<HeaderBar><h1>THIS IS THE NAVBAR</h1></HeaderBar>
</MainContainer>
</>
);
}
I have a problem where the mouse does not follow the div closely due to parent div left and top. Assume parent.jsx is developed by another developer, and I solely can control child.jsx, is there a way for me to make the div follow the mouse?
Here's the parent jsx
import "./styles.css";
import Child from "./child";
export default function Parent() {
return (
<div
style={{
top: "25px",
left: "20px",
position: "relative"
}}
>
<Child />
</div>
);
}
The child jsx
import "./styles.css";
import { useRef } from "react";
export default function Child() {
const descBox = useRef(null);
const handleMove = (e) => {
console.log(e.clientX, e.clientY);
descBox.current.style.left = `${e.clientX}px`;
descBox.current.style.top = `${e.clientY}px`;
};
return (
<>
<div
onMouseMove={handleMove}
style={{
height: "300px",
width: "100%",
backgroundColor: "red"
}}
></div>
<div className="dropdown1" ref={descBox}>
123asdfsfdafffasdfasfdsajkj
</div>
</>
);
}
The css for child
.dropdown1 {
position: absolute;
left: 150px;
top: 10px;
background: #2b4557;
padding: 4px 8px;
font-size: 12px;
line-height: 18px;
color: #fff;
}
Codesandbox to run the code.
As the child is positioned absolute within the relative positioned parent you can work out its left and top positions relative to the parent and use those.
This code adds a small offset to give a slight gap between the cursor and the child (which you may or may not want).
const handleMove = (e) => {
const rect = e.target.getBoundingClientRect();
const x = e.clientX - rect.left + 10;
const y = e.clientY - rect.top + 10;
descBox.current.style.left = `${x}px`;
descBox.current.style.top = `${y}px`;
};
I would like to add some transition styling to my side navigation on my app. I am able to do this using normal classes however in this tutorial they use css modules and i am unsure how to do this using css modules.
I would like my nav to glide in and out, at the moment it jumps statically when the onClick function fires - toggleSideDrawer.
I have used this logic but I am not sure if it is doing anything:
className={props.toggleSideDrawer ? classes.SideDrawerOpen : classes.SideDrawer
Essentially i want that when the user clicks the toggle, the transform property switches from translateX(-100%) to translateX(0) but this is not happening.
Side nav code:
import React from "react";
import Logo from "../../Logo/Logo";
import NavigationItems from "../NavigationItems/NavigationItems";
import Backdrop from "../../UI/Backdrop/Backdrop";
import Aux from "../../../hoc/Aux";
import classes from "./SideDrawer.css";
const SideDrawer = props => {
return (
<Aux classname={classes.SideDrawer}>
<Backdrop
showBackdrop={props.showSideDrawer}
clicked={props.toggleSideDrawer}
/>
{props.showSideDrawer && (
<div
onClick={props.toggleSideDrawer}
className={
props.toggleSideDrawer ? classes.SideDrawerOpen : classes.SideDrawer
}
>
<div className={classes.Logo}>
<Logo />
</div>
<nav>
<NavigationItems />
</nav>
</div>
)}
</Aux>
);
};
export default SideDrawer;
Where the code is used in my Layout component:
import React, { useState } from "react";
import Aux from "../Aux";
import classes from "./Layout.css";
import Toolbar from "../../components/Navigation/Toolbar/Toolbar";
import SideDrawer from "../../components/Navigation/SideDrawer/SideDrawer";
const layout = props => {
const [showSideDrawer, setShowSideDrawer] = useState(false);
return (
<Aux>
<SideDrawer
showSideDrawer={showSideDrawer}
toggleSideDrawer={() => {
setShowSideDrawer(!showSideDrawer);
}}
/>
<Toolbar
onMenuClick={() => {
setShowSideDrawer(!showSideDrawer);
}}
/>
<main className={classes.mainContent}> {props.children} </main>
</Aux>
);
};
export default layout;
CSS:
.SideDrawer {
position: fixed;
width: 280px;
max-width: 70%;
height: 100%;
left: 0;
top: 0;
z-index: 200;
background-color: white;
padding: 32px 16px;
box-sizing: border-box;
transform: translateX(-100%);
}
#media (min-width: 500px) {
.SideDrawer {
display: none;
}
}
.Logo {
height: 11%;
text-align: center;
}
.SideDrawerOpen {
position: fixed;
width: 280px;
max-width: 70%;
height: 100%;
left: 0;
top: 0;
z-index: 200;
padding: 32px 16px;
box-sizing: border-box;
background-color: red;
transform: translateX(0);
transition: transform 0.3s ease-out;
}
The thing is that you need the element will has the transition rule all the time.
My suggestion is to set a static class which which will hold all the styles and addd another one only for overriding transform to make it move.
Something like that (it uses scss but it's easy to do it with css)
.SideDrawer {
position: fixed;
width: 280px;
max-width: 70%;
height: 100%;
left: 0;
top: 0;
z-index: 200;
background-color: white;
padding: 32px 16px;
box-sizing: border-box;
transition: transform .3s ease;
transform: translateX(-100%);
&.show {
transform: translateX(0);
}
}
export const App = () => {
const [showSideDrawer, setShowSideDrawer] = useState(false);
const sidebarClasses = classname([
styles.SideDrawer,
{
[styles.show]: showSideDrawer
}
]);
const ToggleSidebar = () => {
return (
<button onClick={() => setShowSideDrawer(!showSideDrawer)}>
Toggle Sidebar
</button>
);
};
return (
<Fragment>
<h1>App</h1>
<div className={sidebarClasses}>
<div>Sidebar content</div>
<ToggleSidebar />
</div>
<ToggleSidebar />
</Fragment>
);
};
https://codesandbox.io/s/xenodochial-framework-04sbe?file=/src/App.jsx
#MoshFeu helped me fix this.
The problem is that you render the drawer only when showSideDrawer so before it becomes true, the sidebar is not in the DOM yet so the transition is not affecting it.
The solution is to keep it in the DOM all the time but toggle . Open class to change the style.
There are libraries that knows to make the transition works even for elements that are not in the DOM but it's a bit more complicated.
code fix for SideDrawer.js without the conditional within the return
class SideDrawer extends Component {
render() {
let sideDrawerClass = [classes.SideDrawer];
// SideDrawer will now be an array with the side drawer classes and the open class
if (this.props.showSideDrawer) {
sideDrawerClass.push(classes.Open);
}
return (
<Aux classname={classes.SideDrawer}>
<Backdrop
showBackdrop={this.props.showSideDrawer}
clicked={this.props.toggleSideDrawer}
/>
<div
className={sideDrawerClass.join(" ")}
onClick={this.props.toggleSideDrawer}
>
<div className={classes.Logo}>
<Logo />
</div>
<nav>
<NavigationItems />
</nav>
</div>
</Aux>
);
}
}
export default SideDrawer;
I'm making a React Native Karaoke app and I need to do an animation in which a letter is colored from left to right.
Is it possible to apply color to, say, half of a letter?
Aside from my comment, Here is how this type of styling is done. Instead of on hover, you would just animate the width with javascript.
p{
color: black;
position: relative;
display: inline-block;
margin: 0;
font-size: 50px;
}
p:before{
content: attr(data-c);
position: absolute;
width: 0;
overflow:hidden;
top: 0;
left: 0;
color:red;
transition: width 1s;
}
p:hover:before{
width: 100%;
}
<p data-c="Hello">Hello</p>
I tried this you may further apply more animation to it:
import React, { Component } from 'react';
import {
Text,
View,
Animated
} from 'react-native';
export default class AnimatedText extends Component{
componentWillMount() {
this.animatedValue = new Animated.Value(0);
}
componentDidMount() {
Animated.timing(this.animatedValue, {
toValue: 200,
duration: 2500
}).start();
}
render() {
const interpolateColor = this.animatedValue.interpolate({
inputRange: [0, 200],
outputRange: ['rgb(255,255,255)', 'rgb(255, 0, 0)'],
extrapolate: "clamp"
})
const animatedStyle = {
color: interpolateColor,
}
return (
<View style={{flex: 1,justifyContent: 'center',alignItems: 'center',padding:10,backgroundColor:'black'}}>
<Animated.Text style={animatedStyle}>
May be one day so don't turn on the lights I'll give you what you like Give you what you like
</Animated.Text>
</View>
);
}
}
Your solution in expo works if you set a height restriction: https://snack.expo.io/Bko7oYvr7
Trying to build a nifty animation for launching dialogs but running into a snag with ReactCSSTransitionsGroup. The goal is to ensure that the dialog looks like its zooming out of the button that launched it. Below is a sample that shows the working demo.
The math looks good, the css looks good, the component looks good. The unexpected behavior exhibited is the following
Click on the first button (either one). Works perfectly.
Click on the second button, the enter animation does not play.
Doesn't matter how many buttons you add, only the first works as expected. All additional buttons won't show the enter animation properly.
The leave animation works for all buttons.
Trying to figure out if there's something wrong with the code, unintended usage of ReactCSSTransitionsGroup or a bug with it.
Fiddle is here
Thanks!
let ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
let StyleSheet = aphrodite.StyleSheet;
let css = aphrodite.css
const Button = (props) => {
return <div className="button" onClick={(e) => props.onClick(e)}>Click me</div>;
}
let emptyStyleSheet = StyleSheet.create({
enter: {},
enterActive: {},
leave: {},
leaveActive: {}
});
class UnicornDialog extends React.Component {
constructor(props) {
super(props);
this.state = {sheet: emptyStyleSheet};
}
componentWillReceiveProps(nextProps, nextContext){
if (!nextProps.show) {
return;
}
let viewportRect = document.body.getBoundingClientRect();
let sourceRect = nextProps.startRect;
let viewportCenterX = viewportRect.left + (viewportRect.width / 2);
let viewportCenterY = viewportRect.top + (viewportRect.height / 2);
let sourceCenterX = sourceRect.left + (sourceRect.width / 2);
let sourceCenterY = sourceRect.top + (sourceRect.height / 2);
let dx = sourceCenterX - viewportCenterX;
let dy = sourceCenterY - viewportCenterY;
let sheet = StyleSheet.create({
enter: {
opacity: 0,
transform: `translate(${dx}px, ${dy}px) scale(0.01)`
},
enterActive: {
opacity: 1,
transform: "translate(0, 0) scale(1)", transition: "transform 750ms cubic-bezier(0, 0, 0.2, 1), opacity 750ms cubic-bezier(0, 0, 0.2, 1)"
},
leave: {
opacity: 1,
transform: "translate(0, 0) scale(1)"
},
leaveActive: {
opacity: 0,
transform: `translate(${dx}px, ${dy}px) scale(0.01)`,
transition: "transform 750ms cubic-bezier(0, 0, 0.2, 1), opacity 750ms cubic-bezier(0, 0, 0.2, 1)"
}
})
this.setState(sheet);
}
render() {
let child = <div key={"dialog"}
className="dialog"
onClick={this.props.onClick}>click anywhere to dismiss</div>;
if (!this.props.show) {
child = null;
}
return <ReactCSSTransitionGroup
transitionName={{
enter: css(this.state.enter),
enterActive: css(this.state.enterActive),
leave: css(this.state.leave),
leaveActive: css(this.state.leaveActive)
}}
transitionEnterTimeout={750}
transitionLeaveTimeout={750}>
{child}
</ReactCSSTransitionGroup>
}
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = { startRect: null, show: false };
}
showDialog(e) {
let startRect = e.target.getBoundingClientRect();
let show = true;
this.setState({ startRect, show });
}
hideDialog() {
this.setState({ startRect: null, show: false });
}
render() {
return (
<div>
<Button onClick={this.showDialog.bind(this)} />
<Button onClick={this.showDialog.bind(this)} />
<UnicornDialog {...this.state} onClick={this.hideDialog.bind(this)} />
</div>
);
}
}
ReactDOM.render(< Parent />, document.getElementById('container'));
body {
width: 100vw;
height: 100vh;
margin: 0;
padding: 0;
}
.button {
position: absolute;
height: 32px;
line-height: 32px;
width: 128px;
text-align: center;
border: 1px solid rgba(64, 64, 64, 0.1);
background-color: #e74c3c;
color: white;
cursor: pointer;
}
.button:first-child {
top: 64px;
left: 64px;
}
.button:nth-child(2) {
top: 264px;
left: 264px;
}
.dialog {
box-sizing: border-box;
padding: 150px;
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: 100;
background-color: #34495e;
color: #ecf0f1;
cursor: pointer;
font-size: 2rem;
}
<script src="https://npmcdn.com/react#15.4.0/dist/react-with-addons.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://unpkg.com/aphrodite#1.1.0/dist/aphrodite.umd.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
Figured this one out - its a bug in the styles. ReactCSSTransitionGroup will apply both enter and enterActive. When applying those, effectively the enter style is applied but not the active.