react-slick is not working correctly in RTL language in next js app - material-ui

<Slider ref={foodCampaignSliderRef} {...settings} >
{data?.products?.map((product) => {
return (
<WishlistCard
recommenedproducts="true"
product={product}
productImageUrl={
global?.base_urls?.product_image_url
}
datas={data}
/>
)
})}
</Slider>

Related

Accessing Parameters in SolidJS Router

I am trying to rewrite a project I made in React in Solid. I am trying to use the Solid Router as the documentation advises.
Here are my components so far.
index.js
import { render } from 'solid-js/web'
import { Router } from '#solidjs/router'
import './index.css'
import App from './App'
render(
() => (
<Router>
<App />
</Router>
),
document.getElementById('root')
)
App.jsx
import Header from './components/Header'
import styles from './App.module.css'
import Navbar from './components/Navbar'
import Topics from './components/Topics'
function App() {
return (
<div className={styles.container}>
<Header />
<Navbar />
<Routes>
<Route path="/" element={<Articles />} />
<Route path="/:topic" component={<Topics />} />
</Routes>
</div>
)
}
export default App
Navbar.jsx
import { NavLink } from '#solidjs/router'
import { getTopics } from '../utils/api'
const Navbar = () => {
const [topics, setTopics] = createSignal([])
onMount(() => {
getTopics().then(({ topics }) => {
setTopics(topics)
})
})
return (
<nav>
<ul>
<For each={topics()}>
{topic => (
<li>
<NavLink href={`/${topic.slug}`}>{topic.slug}</NavLink>
</li>
)}
</For>
</ul>
</nav>
)
}
export default Navbar
The problem I think seems to be in the component below
Topics.jsx
import { useParams } from '#solidjs/router'
import { createSignal, For, onMount, createResource } from 'solid-js'
import { getTopicArticles } from '../utils/api'
const Topics = () => {
const { topic } = useParams()
console.log(topic)
return (
<div>
<h1>{topic}</h1>
</div>
)
}
export default Topics
The params seem to be undefined no matter what. I understand that Solid router is not exactly the same as React-Router but for this simple example I can't see where I am going wrong.
The desired outcome is to be able to click on the NavLink in the Navbar.jsx component and that routes to the desired path, for example http://localhost:3000/cooking and render the topic I need, but the params are always undefined.
This is the result of the api call, api/articles?topic=undefined
The desired result is to attach the param at the end of the api with useParams, just like in my React version
Edit: below is the Topics.jsx component updated to a working version, not sure if it is the best way.
import { useParams } from '#solidjs/router'
import { getTopicArticles } from '../utils/api'
import Article from './Article'
const Topics = () => {
const params = useParams()
const [articles, setArticles] = createSignal([])
const [loading, setLoading] = createSignal(true)
createEffect(() => {
setLoading(true)
getTopicArticles(params.topic).then(({ articles }) => {
setArticles(articles)
setLoading(false)
})
})
return (
<>
{loading() && <div>Loading...</div>}
<h2>{params.topic}</h2>
<For each={articles()}>{article => <Article article={article} />}</For>
</>
)
}
export default Topics
Could be related to the object returned from useParams is being reactive. console.log returns an empty object but destructing outputs the values as expected. That is because of the proxy and totally normal.
Retrieves a reactive, store-like object containing the current route path parameters as defined in the Route.
https://github.com/solidjs/solid-router#useparams
Also regular query parameters like ?id=1&name=John does not work with useParams, for those use useSearchParams.
import { render } from "solid-js/web";
import {
Router,
useParams,
useSearchParams,
Route,
Routes,
Link
} from "#solidjs/router";
const Home = () => {
const [params, setParams] = useSearchParams();
console.log({ ...params });
return <div>Home</div>;
};
const Blog = () => {
const params = useParams();
console.log({ ...params });
return <div>Blog {JSON.stringify(params)}</div>;
};
const App = () => {
return (
<Router>
<ul>
<li>
<Link href="/?id=1&name=john">Home</Link>
</li>
<li>
<Link href="/blog/js/1">Blog</Link>
</li>
</ul>
<Routes>
<Route path="/" component={Home} />
<Route path="/blog/:category/:id" element={Blog} />
</Routes>
</Router>
);
};
render(App, document.getElementById("app")!);
Check https://codesandbox.io/s/solid-router-demo-forked-71ef9x?file=/index.tsx for live demo.
Also, we pass component name to the component prop like so:
<Route path="/" component={Home} />

React-hook-form + dynamic form: Render element upon dropdown selection

I am working in form using react-hook-form. This form use useFieldArray, it has to be dynamic.
Right now is very simple, it contains a react-select component with a few options and a textfield that get rendered depending on the option that the user select on the select component.
The problem I have is that the textfield component renders when the state updates, which is correct until I add a new group of element to the form. Since the textfield is listening to the same state it doesn't matter which select I use to render the textfield element, it gets rendered in all groups.
I am looking a way to specify which textfield should be rendered when the user change the select.
I the sandbox you can see what I have done. To reproduce the problem click on the "Add"-button and you will see two areas, each one with a select component.
When you choose "Other" in the select component a textfield appears, but not only in the area where the select was changed but in all areas.
How can I avoid that behavior?
https://codesandbox.io/s/vibrant-fast-381q0?file=/src/App.tsx
Extract:
const [isDisabled, setIsDisabled] = useState<boolean>(true);
const { control, handleSubmit, getValues } = useForm<IFormFields>({
defaultValues: {
managerialPositions: [
{
authority: 0,
chiefCategory: 0,
title: 0,
otherTitle: ""
}
]
}
});
useFieldArray implementation:
const {
fields: managerialPositionsFields,
append: managerialPositionsAppend,
remove: managerialPositionsRemove
} = useFieldArray({
name: "managerialPositions",
control
});
Here i update the state when the user select "Other title" in the select component:
const watchChange = (value?: number, i?: number) => {
let values: any = getValues();
if (values.managerialPositions[i].title === 3) {
setIsDisabled(false);
}
};
And here is where I render the button to create a new group of elements and the select component and the textfield that should be rendered if "isDisabled" is false.
{managerialPositionsFields.map((field, index) => {
return (
<Stack className="sectionContainer" key={field.id}>
<Stack horizontal horizontalAlign="space-between">
<StackItem>
<CommandBarButton
iconProps={{ iconName: "AddTo" }}
text="Add"
type="button"
onClick={() => {
managerialPositionsAppend({
authority: 0,
chiefCategory: 0,
title: 0,
otherTitle: ""
});
}}
/>
</StackItem>
</Stack>
<Stack horizontal tokens={{ childrenGap: 20 }}>
<StackItem>
<Label className="select-label requiredIkon">Title</Label>
<Controller
control={control}
name={`managerialPositions.${index}.title`}
render={({ field: { onChange, value, ref } }) => (
<>
<Select
className="react-select-container authoritySelect"
classNamePrefix="react-select"
placeholder="Select title"
options={titelList}
id={`managerialPositions.${index}.title`}
value={
titelList.find((g) => g.value === value)
? titelList.find((g) => g.value === value)
: null
}
onChange={(val) => {
onChange(val.value);
watchChange(val.value, index);
}}
/>
{
// this input is for select validation
<input
tabIndex={-1}
autoComplete="off"
style={{ opacity: 0, height: 0 }}
value={
titelList.find((g) => g.value === value)
? titelList
.find((g) => g.value === value)
.toString()
: ""
}
required={true}
//Without this console will get an error:
onChange={() => {}}
/>
}
</>
)}
/>
</StackItem>
{!isDisabled && (
<StackItem className="">
<Controller
name={`managerialPositions.${index}.otherTitle`}
control={control}
render={({
field: { onChange, name: fieldName, value }
}) => (
<TextField
label="Other title"
name={fieldName}
onChange={(e) => {
onChange(e);
}}
value={value}
/>
)}
/>
</StackItem>
)}
</Stack>
</Stack>
);
})}

How i can set user Image & avatar in the list, if user upload image then show user image otherwise its show the avatar

const ImageDetail = ({ record = {} }) => {
return (
<div>
<Avatar style={{ backgroundColor: colour() }}>
{record.MemberFirstName && record.MemberFirstName.charAt(0)}
{record.MemberLastName && record.MemberLastName.charAt(0)}
</Avatar>
</div>
)
}
This is my Avatar code.
<List>
<Datagrid>
<ImageField label="Image" source="MemberImage.src" />
<ImageDetail source="" label="Image" />
</Datagrid>
</List>
Now I'm using both but I need only one at a time if the user uploads an image show the image otherwise it shows an avatar.
It is enough to pass the image source to the <Avatar/>: src prop and it will do the rest - display the image if available or the default avatar image if not.
<List>
<Datagrid>
<AvatarField label="Image" source="MemberImage.src"/>
</Datagrid>
</List>
...
const AvatarField = ({record, source}) => {
return <Avatar src={record && record[source]}/>
}
Though if you really want to access nested property of the record - e.g. MemberImage["src"] - you might need to swap record[source] with lodash's get utility method -> get(record, source)
const ImageDetail = ({ source, record = {} }) => {
return (
<div>
{(record.MemberImage != undefined && record.MemberImage.src != undefined) ? (
<img width='35' height='35' src={`${record.MemberImage.src}`} />)
: (<Avatar style={{ backgroundColor: colour() }}>
{record.MemberFirstName && record.MemberFirstName.charAt(0)}
{record.MemberLastName && record.MemberLastName.charAt(0)}
</Avatar>)
}
</div >
)
}

ag-Grid Switch goes from checked to unchecked upon down sroll

Getting this weird error where any checked material UI switch becomes unchecked as I scroll down out of that data view.
Below is the Switch return with conditional rendering.
let freeTier = props.params.data.tier;
return freeTier === "FREE" ? (
<FormGroup>
<FormControlLabel
control={
<Switch
disableRipple
focusVisibleClassName={classes.focusVisible}
classes={{
root: classes.root,
switchBase: classes.switchBase,
thumb: classes.thumb,
track: classes.track,
checked: classes.checked
}}
{...props}
/>
}
/>
</FormGroup>
) : null;
And this is where I call the above into cellRendererFramework
cellRendererFramework: params => {
const handleClick = params => {
console.log(params.data);
};
return (
<PaypalSwitch
params={params}
data={params.data}
otherProps={this.props}
onClick={() => handleClick(params)}
/>
);
}
From what it seems like the grid re-renders? I'm getting this error.
ag-Grid: React Component 'cellRendererFramework' not created within
1000ms

Im getting some weird errors with MaterialUI Stepper "Cannot read property stepIndex of undefined"

I'm using MaterialUI and I'm getting the error -
"Uncaught TypeError: Cannot read property 'stepIndex' of undefined"
In my Chrome console
I haven't had this error with any of the other Material-UI React Components. I am pretty new to React so if this is a stupid mistake please bear with me.
I cant seem to solve the problem.
I'm using React 5.3.1.
My code:
class HorizontalLinearStepper extends React.Component {
handleNext() {
const {stepIndex} = this.state;
this.setState({stepIndex: stepIndex + 1,finished: stepIndex >= 2});
};
handlePrev() {
const {stepIndex} = this.state;
if (stepIndex > 0) {
this.setState({
stepIndex: stepIndex - 1
});
}
};
getStepContent(stepIndex) {
switch (stepIndex) {
case 0:
return 'Select campaign settings...';
case 1:
return 'What is an ad group anyways?';
default:
return 'You\'re a long way from home sonny jim!';
}
}
render() {
const {finished, stepIndex} = this.state;
return (
<div>
<Stepper activeStep={stepIndex}>
<Step>
<StepLabel>Select campaign settings</StepLabel>
</Step>
<Step>
<StepLabel>Create an ad group</StepLabel>
</Step>
</Stepper>
<div style={contentStyle}>
{finished ? (
<p>
<a
href="#"
onClick={(event) => {
event.preventDefault();
this.setState({stepIndex: 0, finished: false});
}}
>
Click here
</a> to reset the example.
</p>
) : (
<div>
<p>{this.getStepContent(stepIndex)}</p>
<div style={{marginTop: 12}}>
<FlatButton
label="Back"
disabled={stepIndex === 0}
onTouchTap={this.handlePrev}
style={{marginRight: 12}}
/>
<RaisedButton
label={stepIndex === 2 ? 'Finish' : 'Next'}
primary={true}
onTouchTap={this.handleNext}
/>
</div>
</div>
)}
</div>
</div>
);
}
}
export default HorizontalLinearStepper;
Thanks!
<FlatButton
label="Back"
disabled={stepIndex === 0}
onTouchTap={this.handlePrev.bind(this)}
style={{marginRight: 12}}
/>
<RaisedButton
label={stepIndex === 2 ? 'Finish' : 'Next'}
primary={true}
onTouchTap={this.handleNext.bind(this)}
/>
You need to bind the handlers as they will be run in a different context and will loose the right meaning of this, so we bind the handlers to keep the right context of this.