How to use semantic-ui-react with redux-form? - semantic-ui

Right now I use ReduxForm's Field component and apply raw Semantic UI classes. But I then came across Semantic UI React, which makes things a lot easier -- you can just use React components that have the semantic ui style.
How would you go about integrating ReduxForm with SemanticUIReact?
For example, I currently have something like:
<Field name="gender" component="select" className="ui fluid dropdown">
{genderOptions}
</Field>
But then, I would like to connect Semantic UI React components like the one below to redux-form:
<Form.Field control={Select} label='Gender' options={genderOptions} placeholder='Gender' />
! Note Field is from redux-form and Form.Field is from semantic-ui-react

Create a component like this:
import React, { PropTypes } from 'react'
import { Input } from 'semantic-ui-react'
export default function SemanticReduxFormField ({ input, label, meta: { touched, error, warning }, as: As = Input, ...props }) {
function handleChange (e, { value }) {
return input.onChange(value)
}
return (
<div>
<As {...input} value={input.value} {...props} onChange={handleChange} error={touched && error} />
{touched && (warning && <span>{warning}</span>)}
</div>
)
}
SemanticReduxFormField.propTypes = {
as: PropTypes.any,
input: PropTypes.any,
label: PropTypes.any,
meta: PropTypes.any
}
Then in your component call your field like this:
import { Form } from 'semantic-ui-react'
import { reduxForm, Field } from 'redux-form'
class MyComponent extends Component {
render () {
return (
<Form>
<Field component={SemanticUiField} as={Form.Select} name='firstname' multiple options={options} placeholder='Select...' />
</Form>
)
}
}
export default reduxForm({...})(MyComponent)

Related

How can I mix between a ssr component and a client component in Nextjs 13?

The point is to implement a dynamic SSR component can be re-rendered by a search input.
I solved this by creating a layout.tsx file on my specific router then import children which made me dynamic render ssr component by the client component:
Layout.tsx
import React, { Suspense } from "react";
import Search from "./Search";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<div className="layout">
<Search />
{children}
</div>
);
}
Search.tsx
"use client";
import { FormEvent, useState } from "react";
import { useRouter } from "next/navigation";
export default function Search() {
const [text, setText] = useState<string>("")
const router: any = useRouter();
const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
setText('')
router.push(`/definition/${text}`)
}
return (
<form onSubmit={handleSubmit} className='search'>
<input onChange={(e) => setText(e.target.value)}
value={text} type="text"
placeholder={"write to search"} />
</form>
);
} );
}

Keep the list open when selecting an item

I would like to create a CSS element such that:
There is a button.
Clicking on the button opens a list (e.g., a dropdown list) of items.
We can click on the items to select and the parent component is systematically informed.
We click on the area outside the list (e.g., clicking on the button again) to close the list.
I have made a normal dropdown list with the following code by Dropdown (one version and another preview version) of Fluent UI (codesandbox: https://codesandbox.io/s/inspiring-lovelace-ivln6v?file=/src/App.js). It does not fulfil the 4th condition above: selecting an item will systematically close the dropdown, whereas I would expect the list is still open and clicking on the area outside the list (e.g., clicking on the button again) closes the list.
Note that this is the default behavior of controlled multi-select Dropdown, where we have to click on the area outside the dropdown (e.g., clicking on the button again) to close the dropdown. So it's not an unreasonable need.
Does anyone know how to make such a CSS element (probably by adjusting existing controls)? I'm open to list controls such as Dropdown, Select and Combobox of libraries such as Fabric UI, Fluent UI, Material UI.
import React from "react";
import { Dropdown } from "#fluentui/react/lib/Dropdown";
import { initializeIcons } from "#fluentui/react/lib/Icons";
initializeIcons();
const numberOptions = [8, 9, 10].map((i) => ({
key: i,
text: "Number: " + i.toString()
}));
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = { number: 8 };
}
onnumberChange = (_ev, option) => {
if (typeof option.key === "number") {
this.setState({ number: option.key });
}
};
render() {
return (
<div>
{`Number: ${this.state.number}`}
<br />
<br />
<Dropdown
options={numberOptions}
defaultSelectedKey={this.state.number}
onChange={this.onnumberChange}
/>
</div>
);
}
}
A workaround is to use open, onOpenChange, onOpenSelect of the preview version of Dropdown.
CodeSandbox: https://codesandbox.io/s/inspiring-almeida-3lgtcy?file=/src/App.js
import React from "react";
import { Dropdown, Option } from "#fluentui/react-components/unstable";
import { FluentProvider, webLightTheme } from "#fluentui/react-components";
import { initializeIcons } from "#fluentui/react/lib/Icons";
initializeIcons();
const numberOptions = ["8", "9", "10"];
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = { number: "9", op: false };
}
render() {
return (
<FluentProvider theme={webLightTheme}>
<div>
{`Number: ${this.state.number}`}
<br />
<br />
<Dropdown
open={this.state.op}
onOpenChange={(e, data) =>
this.setState(
{ op: data.open },
console.log("onOpenChange", this.state.op ? "closed" : "open")
)
}
onOptionSelect={(e, data) =>
this.setState({ op: true, number: data.optionText })
}
defaultSelectedOptions={["9"]}
>
{numberOptions.map((option) => (
<Option key={option}>{option}</Option>
))}
</Dropdown>
</div>
</FluentProvider>
);
}
}

How to customize checkbox style with react-bootstrap?

I'm using react-bootstrap. I'm trying to style a custom checkbox since it seems it makes it possible. Tho, it doesn't work. I'm doing what the documentation tells me.
This is my code.
import * as React from "react";
import { t as typy } from 'typy';
import _ from 'lodash';
import { Form, FormCheck } from "react-bootstrap";
import { ErrorMessage } from "formik";
export type Props = {
isChecked: Boolean,
changeHandler: Function
}
export const Checkbox = ({
isChecked,
changeHandler
}: Props) => {
return (
<Form>
{['checkbox', 'radio'].map((type) => (
<div key={`custom-${type}`} className="mb-3">
<Form.Check
custom
type={type}
id={`custom-${type}`}
label={`Check this custom ${type}`}
/>
<Form.Check
custom
disabled
type={type}
label={`disabled ${type}`}
id={`disabled-custom-${type}`}
/>
</div>
))}
</Form>
);
};
export default Checkbox;
This is my css. I just want to see if it applies the style:
#custom-checkbox {
background-color: red;
width: 10rem;
}
You can use .custom-control-input and .custom-control-label classes to apply custom style to the custom checkbox in react-bootstrap.

Definitive guide for styling react-tooltip components?

I am using react-tooltip, react-emotion.
I cannot figure out how to style the span in order to override default styles.
Here's what I've got so far:
import React, { PureComponent } from 'react';
import styled from 'react-emotion';
const myTooltip = (Wrapper, toolTip) => {
class TooltipWrap extends PureComponent {
render() {
return (
<span
data-tip={toolTip}
data-delay-show="250"
data-place="bottom"
className={TooltipStyle}
>
<Wrapper
{...this.props}
/>
</span>
);
}
}
return TooltipWrap;
};
export default withToolTip;
const TooltipStyle = styled.span ({
color: 'red !important';
fontSize: '48px !important';
})
Anyone have any tips or a specific definitive guide on how to style this span so I can override the defaults in react-tooltip?
The documentation is pretty spotty, and there's literally no examples anywhere on the web.
I ran into a similar issue but was able to override the default styles using styled components and passing it the ReactTooltip component
import React, { PureComponent } from 'react';
import styled from 'react-emotion';
import ReactTooltip from 'react-tooltip';
const myTooltip = (Wrapper, toolTip) => {
class TooltipWrap extends PureComponent {
render() {
return (
<span
data-tip={toolTip}
data-delay-show="250"
data-place="bottom"
>
// Replace ReactTooltip component with styled one
<ReactTooltipStyled type="dark" />
<Wrapper
{...this.props}
/>
</span>
);
}
}
return TooltipWrap;
};
export default withToolTip;
export const ReactTooltipStyled = styled(ReactTooltip)`
&.place-bottom {
color: red;
font-size: 48px;
}
`;
Using this method all you would need to do is import the newly styled component into your React file and replace the original ReactTooltip with the ReactTooltipStyled component.

InitialValues aren't populating redux form

At the moment, I'm having difficulty populating the input fields for a redux form with initial values. Could someone please tell me what's wrong with the following code, or if this is a known issue? Thanks for the help and support.
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Field, reduxForm, reset, initialize } from 'redux-form'
const renderField = props => (
<div>
<label>{props.placeholder}</label>
<div>
<input {...props}/>
{props.touched && props.error && <span>{props.error}</span>}
</div>
</div>
)
class EditArtist extends Component {
render() {
const { initialValues} = this.props;
console.log(initialValues)
return (
<form>
<Field name="name" component={renderField} type="text" placeholder="Name"/>
</form>
)
}
}
const validate = values => {
const errors = {};
return errors;
}
const mapStateToProps = (state) => ({
initialValues: {
name: "COOL"
}
});
export default connect(mapStateToProps)(reduxForm({
form: 'edit_artist_form',
validate,
enableReinitialize: true
})(EditArtist));

Resources