React DropDown Component on FabricJS Canvas - javascript

I am able to create a TextBox on FabricJS Canvas. But I am unable to create a Dropdown on FabricJS Canvas. There is an option to create a TextBox on FabricJS using fabric.Textbox but the same cannot be done for dropdown. Please see my codes below on how I create a Textbox on FabricJs and kindly advise on how I can do the same If I want to create a DropDown component on a FabricJS canvas.
If there any options other than using FabricJS that allows more flexibility and it is abetter option for creating complex components, kindly share a link or source to help me.
My Codes on how I create a Textbox on FabricJS canvas
export default function TextBox(props) {
useEffect(() => {
var text = new fabric.Textbox("Enter Text Here", {
left: 10,
top: 50,
width: 294,
height: 60,
fontStyle: "normal",
color: "#999999",
fontWeight: 375,
fontSize: 12,
backgroundColor: "#ffffff",
borderColor: "#ABB3BF",
padding: 20,
showTextBoxBorder: true,
textboxBorderColor: "green",
borderStyle: "solid",
});
props.canvas.add(text);
});
return null;
}

I don't think that you can do that by default in FabricJS. But you can add custom control on fabric objects, then add your submenu/dropdown component as a context menu. There are several context-menu libraries for ReactJS, like "React-Contextify".

Related

Rotate a MUI LinearProgress

I'm trying to make a graph chart with MUI using the LinearProgress component with some styling the basic idea is to get this to rotate 90deg
const BorderLinearProgressBottom = withStyles((theme) => ({
root: {
height: 50,
borderRadius: 5,
},
colorPrimary: {
backgroundColor:
theme.palette.grey[theme.palette.type === "light" ? 200 : 700],
},
bar: {
borderRadius: 5,
backgroundColor: "#00A99E",
},
transform: [{ rotate: "90deg" }],
}))(LinearProgress);
gets my
<BorderLinearProgressBottom
variant="determinate"
value={22}
/>
to look like this
How can I get it to rotate by 90deg?
I tried putting in the BorderLinearProgressBottom transform: [{ rotate: "90deg" }], but that did not work.
Code Sandbox
Please don't use rotate(-90deg) if you want to display the LinearProgress vertically, it will break your layout because transform only scales the element visually without changing the size, so a rotated LinearProgress still occupies the space as if it's laid out horizontally. To rotate both its appearance and size, you should have a look at the implementation of Slider for reference. But I'll write it down for you now to save time.
First off you need to swap the height and width of the ProgressBar container:
// before
height: 50, // restrict the height
width: 'auto', // expand as long as you want (inside container)
// after
width: 50, // restrict the width
height: '100%', // expand as high as you want (inside container)
Then rotate the progress bar inside. This transform works because it only transforms 'locally' (the bar position is absolute inside the container).
bar: {
// the default style uses translateX, so we need to switch the axis
transform: ({ value }) => {
return `translateY(${value}%) !important`;
}
}
And that's it. You're done. Not it will look like a vertical Slider.
Live Demo

Override Material UI shadow array values in theme overrides using createMuiTheme

I have a custom theme for my toolkit and am using createMuiTheme to override the palette, fonts, etc. I am attempting to slim down the shadow array in the theme object which is used for various components, which by default comes with 25 values. I only want to offer two options in my shadow array to keep things simple.
When I pass the two values I want to support for shadows into the array I get a warning from MUI:
index.js:1437 Warning: Material-UI: the shadows array provided to createMuiTheme should support 25 elevations.
So i've gotten around this by adding setting "none" for the other shadows that I don't want set values for like so:
let theme = createMuiTheme({
palette: {
common: {
black: "#000",
white: "#fff",
...
},
typography: {
fontFamily: opensans,
...
},
shadows: [
`0px 0px 6px 0px ${hexa(grey[500], 0.25)}`,
`0px 0px 6px 0px ${hexa(grey[500], 0.55)}`,
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
etc...
]
});
This is not ideal since it bloats the theme a ton which developers use as a ref to see whats available to use, is there a way around this?
My ideal state is representation in the theme object that looks like this but with no console warnings:
let theme = createMuiTheme({
palette: {
common: {
black: "#000",
white: "#fff",
...
},
typography: {
fontFamily: opensans,
...
},
shadows: [
`0px 0px 6px 0px ${hexa(grey[500], 0.25)}`,
`0px 0px 6px 0px ${hexa(grey[500], 0.55)}`,
]
});
You probably could do something like:
const makeTheme = () => {
const original = createMuiTheme();
return {
...original,
// override shadows based on the original array
shadows: original.shadows.map(() => 'none'),
};
};
const theme = makeTheme();
Actually you shouldn't be doing this as by this way what you are doing is that you are removing all the other default shadows given by material ui, this will make some components behave in some weird way, as it won't find the shadow, as you have overridden them.
Better approach is to add another customShadow key in the theme, and add your custom shadows to it. This way you are no longer overriding the default shadows that comes loaded with material ui and all the components that uses those shadows will work without any problem.
I hope you got your answer

How to custom color text and icon in TableSortText component of Material-ui?

What I'm trying to do:
I am trying to provide the user the option to provide custom styling to my EnhancedTable component by passing in a styles object containing properties such as headCellColor, headCellBackgroundColor, bodyCellColor, bodyCellBackgroundColor etc which can be used to color the cells in TableHead and TableBody.
In the TableHead component, I use a TableSortLabel in a way similar to what they've done in this material-ui docs example: https://material-ui.com/components/tables/#sorting-amp-selecting
I wish to custom color the text and the arrow icons on hover and when active based on the props provided by the user.
Let's see the colors of TableSortLabel in different situations:
The color of the text is grey initially and there is no arrow. When mouse is hovered over it, a grey arrow appears and the text turns black. On clicking it, active state is set, the grey arrow turns black and the text turns black permanently until active state is removed.
What I've tried so far:
const useStyles = makeStyles({
tableSortLabel: props => ({
backgroundColor: "blue",
color: props.headCellColor,
fill: props.headCellColor,
"&:hover": {
backgroundColor: "blue"
}
})
});
function EnhancedTableHeadCell(props) {
const { isActive, onHoverSortState, clickHandler, ...otherProps } = props;
const classes = useStyles(props.styles);
return (
<FancyTableCell styles={props.styles} {...otherProps}>
<TableSortLabel
active={isActive}
classes={{
icon: classes.tableSortLabel,
active: classes.tableSortLabel
}}
direction={onHoverSortState}
onClick={clickHandler}
>
{props.children}
</TableSortLabel>
</FancyTableCell>
);
}
This is what it looks like in the browser:
https://i.postimg.cc/fW7W2MRB/c1.jpg
The first one is a normal header, the second is on hover and the third is when clicked (active state).
From what we can observe, the text color is totally unaffected by the color css property in all the three cases (normal, hover, active). On hover, backgroundColor only affects the icon and not the text. However, we can see that backgroundColor affects the text when it is active. Everything is going as expected with the icon. The only issue is with the text.
What could I be possible doing wrong? How can I solve my problem?
What worked for me is:
const StyledTableSortLabel = withStyles((theme: Theme) =>
createStyles({
root: {
color: 'white',
"&:hover": {
color: 'white',
},
'&$active': {
color: 'white',
},
},
active: {},
icon: {
color: 'inherit !important'
},
})
)(TableSortLabel);
You can reference the following for increasing css specificity:
https://material-ui.com/customization/components/#pseudo-classes
Solution for your problem is following:
MuiTableSortLabel: {
root: {
color: textPrimary,
// if you want to have icons visible permanently
// '& $icon': {
// opacity: 1,
// color: primaryMain
// },
"&:hover": {
color: primaryMain,
'&& $icon': {
opacity: 1,
color: primaryMain
},
},
"&$active": {
color: primaryMain,
// && instead of & is a workaround for https://github.com/cssinjs/jss/issues/1045
'&& $icon': {
opacity: 1,
color: primaryMain
},
},
},
}
This restyling I use globally via my ThemeProvider, but you can of course use it individually in your single component by using "withStyles" HOC (see "BootstrapButton" in example)
I could'nt find a proper way to do it so I came up with a temporary solution overriding the material ui css.
I added this to my global css:
.MuiTableSortLabel-root.MuiTableSortLabel-active,
.MuiTableSortLabel-root:hover,
.MuiTableSortLabel-icon {
color: inherit !important;
}
Worked for me with Mui5:
sx = {
{
'&.MuiTableSortLabel-root': {
color: 'white',
},
'&.MuiTableSortLabel-root:hover': {
color: 'blue',
},
'&.Mui-active': {
color: 'blue',
},
'& .MuiTableSortLabel-icon': {
color: 'blue !important',
},
}
}
'&.MuiTableSortLabel-root' <-- no space &.
'&.Mui-active' <-- no space &.
'& .MuiTableSortLabel-icon' <-- space

Change React-Table default styling

I have a react-table, each row has the arrow that when clicked expands into a sub-component of another react-table.
I want to change the color of that arrow as well as move it to the right side of the column if possible. Does anyone know if that's possible and how to go about doing that. I've attached a pic of the code for the table as well as how it looks rendered currently. Thanks for any help!
Code example
It's possible by using a Custom Expander. You can just define your column like this:
columns: [
// other columns...,
{
expander: true,
Header: () => <strong>More</strong>,
width: 65,
Expander: ({ isExpanded, ...rest }) =>
<div>
{isExpanded
? <span>⊙</span>
: <span>⊕</span>}
</div>,
style: {
cursor: "pointer",
fontSize: 25,
padding: "0",
textAlign: "center",
userSelect: "none",
color: "green"
},
Footer: () => <span>♥</span>
}
]

What's the most performant but full-featured styling method in React.js

I have been reading a lot blog posts, best practices and slides (e.g. CSS in JS by Christopher Chedeau aka 'vjeux' which I think is great).
I totally understand why it is "better" to set your styling directly within your React Component, but I then found out that this might be limited as well. You may not use CSS pseudo-classes nor media queries to handle some responsive styling issues.
As someone who is used to do a lot of work with CSS and lately with SASS (which I still love) this drives me in some kind of cleavage, because I do not want to disclaim any styling property which standard CSS gives me.
My question now is:
Is it possible to have your styling within your React Components without those given disadvantages, and if: How would you actually do it to achieve the best performance and maximum of clarity.
Check out https://github.com/FormidableLabs/radium. It's pretty cool. Here's an example where they show how to add media queries among other things.
var styles = {
base: {
backgroundColor: '#0074d9',
border: 0,
borderRadius: '0.3em',
color: '#fff',
cursor: 'pointer',
fontSize: 16,
outline: 'none',
padding: '0.4em 1em',
':hover': {
backgroundColor: '#0088FF'
},
':focus': {
backgroundColor: '#0088FF'
},
':active': {
backgroundColor: '#005299',
transform: 'translateY(2px)',
},
// Media queries must start with #media, and follow the same syntax as CSS
'#media (min-width: 992px)': {
padding: '0.6em 1.2em'
},
'#media (min-width: 1200px)': {
padding: '0.8em 1.5em',
// Media queries can also have nested :hover, :focus, or :active states
':hover': {
backgroundColor: '#329FFF'
}
}
},
red: {
backgroundColor: '#d90000',
':hover': {
backgroundColor: '#FF0000'
},
':focus': {
backgroundColor: '#FF0000'
},
':active': {
backgroundColor: '#990000'
}
}
};

Categories

Resources