How to use react-jsonschema-form with material-ui? - css

I am doing a form using react-jsonschema-form, but i really want to customize my application (including the form) with the Material-UI.
I am having trouble to use both together because react-jsonchema-form uses a uiSchema for styling and the Material-UI is set on a prop like this :
SimpleModal.propTypes = {
classes: PropTypes.object.isRequired,
};
<FormControl className={classes.formControl}>
How can i use the Material-UI inside the schema forms?

Now you can start use it with standard react-jsonschema-form library! I searched for a long time and found that now it can already be done.
This PR explain using HOC: https://github.com/mozilla-services/react-jsonschema-form/issues/1222
GitHub: https://github.com/cybertec-postgresql/rjsf-material-ui
Playground with material-ui components: https://cybertec-postgresql.github.io/rjsf-material-ui/
import { withTheme } from 'react-jsonschema-form';
import { Theme as MuiTheme } from 'rjsf-material-ui';
const Form = withTheme(MuiTheme);

If you want use component in material UI i did like this...
import material UI
import TextField from '#material-ui/core/TextField'
declare constant and costum widgets
const MyCustomWidget = props => {
return (
<TextField
type="text"
label="Name1"
value={props.value}
onChange={event => props.onChange(event.target.value)}
margin="normal"
/>
)
}
const widgets = {
TextWidget: MyCustomWidget,
}
and in the return of my component
return (
<div>
{' '}
<Form schema={schema1} widgets={widgets} >
{/* this is for disable the button Submit of Form */}{' '}
</Form>
</div>
It works for me

Weird to see there's no answer.
Quick answer: you cant!
Check out project's FAQ about that, it says:
Q: Will react-jsonschema-form support Material, Ant-Design, Foundation, or [some other specific widget library or frontend style]?
A: Probably not. We use Bootstrap v3 and it works fine for our needs. We would like for react-jsonschema-form to support other frameworks, we just don't want to support them ourselves. Ideally, these frontend styles could be added to react-jsonschema-form with a third-party library.
But! ... :) don't go so fast!
The closest I have come to achieve a Material "look and feel" was to use a Bootstrap Theme, Paper by Bootswatch which is quite nice!
Hope this helps anyone

Related

Using Tailwind Forms Plugin with React Select

I am trying to integrate Select from react-forms with tailwind css and the tailwind forms plugin (#tailwindcss/forms).
With only tailwind and react-select, the form renders correctly. However, with the plugin, an outline appears. I would like for tailwindcss forms not to interfere with react-select styling. Is there an effective solution to allow react-select styles to override tailwind plugins?
Additionally, please let me know if there are any effective solutions for styling react-select forms using tailwind without resorting to other libraries, like emotion or styled-components.
You can set the box shadow to none for the input when focused
<Select
....
styles={{
input: (base) => ({
...base,
'input:focus': {
boxShadow: 'none',
},
}),
}}
/>
Additionally, please let me know if there are any effective solutions
for styling react-select forms using tailwind without resorting to
other libraries, like emotion or styled-components.
The answer to this is to use this library
https://github.com/ben-rogerson/twin.macro
Example, you can do something like this:
import tw from 'twin.macro';
import ReactSelect, { Props } from 'react-select';
const Styled = {
Select: tw(ReactSelect)`rounded-lg text-center border-2`
};
const Select: React.FC<Partial<Props>> = (props) => {
return (
<Styled.Select {...props} />
);
};
You could use the class strategy for the plugin, it will disable the extra styling, but you will need to implement the form-* class to every other input.
Here is the documentation for it.

using material-ui for react in a wordpress plugin: css specificity problems

Im trying to properly use material-ui for react in a wordpress plugin.
Problems arise when using inputs for forms and the styling being overwritten by wordpress own styling in the forms.css file.
Im struggling to find a solution for material-ui writing css that has better specificity than forms.css without having to rewrite the styling(I dont wont my own custom styling for material-ui components: I want to use the default one)
Here is an example(text has been edited for readability(removed selectors that dont matter and styling):
react jsx:
<div id='ad-campaign-edit' style={modalStyle} className={classes.root}>
<form
className={classes.form}
noValidate
autoComplete='off'
>
<TextField
id='ad-campaign-name'
className={classes.textField}
variant='filled'
label='Navn på kampanjen'
/>
<TextField
id='ad-campaign-sub-title-text'
className={classes.textField}
variant='filled'
label='Undertekst'
/>
<TextField
id='ad-campaign-sub-price'
className={classes.textField}
variant='filled'
label='Pris'
/>
<Checkbox
defaultChecked
className={classes.textField}
color='primary'
inputProps={{ 'aria-label': 'secondary checkbox' }}
/>
</form>
</div>
forms.css(WP):
input[type="text"], {
...
}
generated css from material-ui:
.MuiInputBase-input {
...
}
other things to note: the css from material-ui is generated after the styling from wordpress in the dom.
Looking at the rules for css specificity(ref www.specifishity.com) forms.css is (0-1-1) and material-ui is (0-1-0).
My question is: how can I make material-ui take presedence without having to rewrite all the css with something like the makeStyles hook?(Can I add better specificity to material-ui in general?)
edit: Forgot to add html/jsx
edit2: rewrote specificity understanding.
I solved it, it's working but not completely.
This solution can be a starting point.
You need to install this npm
https://www.npmjs.com/package/jss-increase-specificity
Then you have to create a <StyleProvider> like described here
https://material-ui.com/styles/advanced/#jss-plugins
What I did
import { create } from 'jss';
import { StylesProvider, jssPreset } from '#material-ui/core/styles';
import increaseSpecificity from 'jss-increase-specificity';
const jss = create({
plugins: [...jssPreset().plugins, increaseSpecificity({ repeat: 1 })],
});
export default function App() {
return (
<StylesProvider jss={jss}>
...
</StylesProvider>
);
}

Flags inside a React Bootstrap select option renders as [object, object]

I want to display Flags icons inside a React Bootstrap selection Option. I have tried both CSS based and React based libraries to do so and in each case I get only [object object]
I have tried with the https://github.com/lipis/flag-icon-css CSS library
<Form.Control as="select">
<option><span className="flag-icon flag-icon-gr"></span></option>
</Form.Control>
Which gives me a warning and the same [Object object]
Warning: Only strings and numbers are supported as <option> children.
I have also attempted with the React wrapper for the same library https://www.npmjs.com/package/react-flag-icon-css
<Form.Control as="select">
<option><FlagIcon className="countryIcon" code="us" size="lg"/></option>
</Form.Control>
Which does not generate a warning but no results either
Does anyone know how I can get something else than string or number in the Option, or another way to include an icon ?
Option HTML tag accepts text only, it can't accept any other HTML, it will strip it. You can check this React issue [bug][16.5.0] option returns [object Object] instead of string and read the comment by Dan Abramov:
I don't think it was strictly a regression. This is kind of a thorny
area. It was never intentionally supported. It accidentally worked on
initial mount but then crashed on updates (#13261). Fixing the crash
was more important, so we fixed it to be treated as text content
(which it should be). Unfortunately this means putting custom
components in the middle is not supported. That's consistent with how
textarea and similar elements work.
I think it's better to show invalid output and warn about something
that breaks on updates, than to let people use it only to discover it
crashes in production. But I can see arguments for why this should be
supported when the custom component returns a string. Unfortunately I
don't know how to fix it in a way that would both solve the update
crashes and support text-only content. I think for now it's reasonable
to say putting custom components into doesn't really work
(and never quite worked correctly), and ask you to manually provide a
string to it.
Alternatively, you can use Bootstrap Dropdowns to create a dropdown button with a list of countries using the code below:
App.js:
...
import Dropdown from 'react-bootstrap/Dropdown';
import FlagIcon from './FlagIcon.js'
function App() {
const [countries] = useState([
{ code: 'gr', title: 'Greece'},
{ code: 'gb', title: 'United Kingdom'},
{ code: 'us', title: 'United States'}
]);
const [toggleContents, setToggleContents] = useState("Select a country");
const [selectedCountry, setSelectedCountry] = useState();
return (
<div className="App">
<Form>
<Dropdown
onSelect={eventKey => {
const { code, title } = countries.find(({ code }) => eventKey === code);
setSelectedCountry(eventKey);
setToggleContents(<><FlagIcon code={code}/> {title}</>);
}}
>
<Dropdown.Toggle variant="secondary" id="dropdown-flags" className="text-left" style={{ width: 300 }}>
{toggleContents}
</Dropdown.Toggle>
<Dropdown.Menu>
{countries.map(({ code, title }) => (
<Dropdown.Item key={code} eventKey={code}><FlagIcon code={code}/> {title}</Dropdown.Item>
))}
</Dropdown.Menu>
</Dropdown>
</Form>
</div>
);
}
FlagIcon.js:
import React from 'react';
import FlagIconFactory from 'react-flag-icon-css';
// const FlagIcon = FlagIconFactory(React);
// If you are not using css modules, write the following:
const FlagIcon = FlagIconFactory(React, { useCssModules: false })
export default FlagIcon;
You'll get a dropdown button like this:
You can also check this working Stackblitz: https://stackblitz.com/edit/react-bootstrap-flags-dropdown-menu
Are you closing the tag
<Form.Control as="select">
[object Object] is displayed e.g when you are concatenating a string with an object, for example:
console.log(""+{})

How to use react-jss within react class Components?

In react-jss documentation, the authors have written:
'HOC based API is deprecated as of v10 and will be removed in v11.'
This means, as far as I understand, that such HOC functionality as injectSheet and withStyles will no longer be available in V11.
The new react-based stylesheet generating functions seem to be all based on react hooks. The function createUseStyles seemed very promising to myself and my team, until upon looking further into the source code we realised that it was only available within functional components, as it makes use of hooks.
The Problem
As a team we still make heavy use of React Class components and have no plans to move completely to hooks, not because hooks aren't useful, but because sometimes functional components aren't the best or most organised solution to writing a component.
Perhaps I'm missing something-- but it seems like there is now no solution left for React Class based components, other than writing our own manual implementation from core jss.
What solutions are there for a developer to make use of react-jss in a way similar to that achieved by createUseStyles, keeping up with the latest version of react-jss, being able to pass dynamic props, and etc. without writing a manual implementation?
While not specific to JSS, keep in mind that you can always use a tiny wrapper to convert any Hook to render prop or a HOC.
Converting Hook to a render prop is described here: https://reacttraining.com/blog/using-hooks-in-classes/
You can use a similar approach to convert any Hook to a HOC.
import { Classes } from 'jss';
import { createUseStyles } from 'react-jss';
First, lets create a more type safe function for creating styles.
export function createStyles(classes: { [name: string]: Partial<CSSStyleDeclaration> }) {
return createUseStyles(classes as any);
}
Secondly, we'll create a simple wrapper to allow hooks for our components.
function Styles<T extends string | number | symbol>(props: { styles: () => Classes<T>, children: (classes: Classes<T>) => ReactElement }) {
const classes = props.styles();
return props.children(classes);
}
Example
const styles = createStyles({
title: {
fontSize: '25px',
textTransform: 'uppercase'
},
message: {
color: 'red'
}
});
export const App = () => (
<Styles styles={styles}>
{classes => (
<Fragment>
<h1 className={classes.title}>Title</h1>
<p className={classes.message}>message</p>
</Fragment>
)}
</Styles>
);
Output

Meteor React - Why are React Components defined differently in React Mounter vs React Layout from Kadira?

I am looking forward to Meteor 1.3 so I can import React components instead of having them as globals.
Been following this tutorial (https://voice.kadira.io/getting-started-with-meteor-1-3-and-react-15e071e41cd1) and I noticed I will have to use React-mounter instead of React-Layout from Kadira
In these docs here:
https://github.com/kadirahq/react-mounter
I see that the React components are defined like this:
const MainLayout = ({content}) => (
<div>
<header>
This is our header
</header>
<main>
{content}
</main>
</div>
);
Instead of something like this
MainLayout = React.createClass({
propTypes: {
content: React.PropTypes.element
},
render() {
return (
<div>
<header>
This is our header
</header>
<main>
{this.content}
</main>
</div>
);
}
});
Can you help explain to me what is happening here? Also how do I use this new style? Where to define all the properties, methods, mixins, etc?
Also as a side question, I noticed React was added as an npm package, instead of using Meteor add react. Is this how we are supposed to add react now?
You could categorize your components in two types: containers and presentational components.
For more details see this
React v0.14 introduced something called functional components which are presentation components that are created via a function instead of a class instance.
Since they are presentational components they are not intended to have more methods or mixins or anything, they just display data.
If you want to stick with React v0.14 and ES2015 you could create your components like
class Component extends React.Component {
componentWillReceiveProps(nextProps) {
console.log('componentWillReceiveProps', nextProps.data.bar);
}
render() {
return <div>Bar {this.props.data.bar}!</div>;
}
}
You now have a full component that can have state, other event handlers and other methods.
A very important thing to note here is that the ES2015 syntax does not allow mixins because they prefer inheritance or functional composition.
Hope that helps!
Sorry I can't help you with your side question, haven't use React with Meteor.

Resources