How to get width form keen-slider/react - reactjs

I need to know the width of each slide in the carousel to make the height the same. That way every element of the slider will be square.
I tried to find information in the documentation. I didn't find anything I needed.

I got this solution
const [ref, internalSlider] = useKeenSlider({...})
const slideHeight = internalSlider.current?.slides?.[0]?.clientWidth;
<div ref={ref} className="keen-slider">
{slides.map(slide => (
<div style={{ height: slideHeight }}/>
)}
</div>

Related

React-virtualized Cellmeasurer defaulting to 'minHeight' of the CellMeasurerCache

I'm using a react-virtualized List component, which uses height data from CellMeasurerCache:
const cache = new CellMeasurerCache({fixedWidth: true, rowHeight: 150, minHeight: 50 });
This is the code for the list:
return (
<div className={classes.maxHeight}>
<AutoSizer>
{({height, width}) =>
<List
className='List'
height={height}
width={width}
overscanRowCount={5}
rowCount={content.length}
rowHeight={cache.rowHeight}
rowRenderer={listRowRenderer(content)}>
</List>
}
</AutoSizer>
</div>);
The problem is that, sometimes the height is defaulting to minHeight, and i want it to use the actual computed height
See this image , the two cards have a default height of 50, when they should have a computed height based on their content. If I scroll down and back up, they will be computed properly, so should this be forced somehow or...?
The listRowRenderer:
const item = data[index];
return (
<CellMeasurer
cache={cache}
columnIndex={0}
key={key}
rowIndex={index}
parent={parent}>
{({measure, registerChild}) =>
<div ref={registerChild} style={style}>
(content here)
</div>
}
</CellMeasurer>
);
I even tried using the measure from CellMeasurer inside useEffect of the card component
Turns out it's not okay to use 1 cache in multiple locations. I had an UI with 3 tabs, each tab loading virtualized data, and each tab used the same cache which messed things up. I gave each tab it's individual cache and voila it worked.

How can I access the "arrow" button click event on Material UI data grid?

In the documentation of Material UI Data Grid it has this code snippet (I've made a couple slight changes like importing DataGrid instead of DataGridPro, etc.):
import { DataGrid, useGridApiRef } from '#material-ui/data-grid';
import Alert from '#material-ui/lab/Alert';
export default function PageChange() {
const apiRef = useGridApiRef();
const [message, setMessage] = React.useState('');
const data = {'dummy-data-for-now': ''};
React.useEffect(() => {
/* ---- Theoretically I would replace columnResize with 'pageChange' ---- */
return apiRef.current.subscribeEvent('columnResize', (params) => {
setMessage(
`Column ${params.colDef.headerName} resized to ${params.computedWidth}px.`,
);
});
}, [apiRef]);
return (
<div style={{ width: '100%' }}>
<div style={{ height: 180, width: '100%' }}>
<DataGrid apiRef={apiRef} {...data} />
</div>
{message && (
<Alert severity="info" style={{ marginTop: 8 }}>
{message}
</Alert>
)}
</div>
);
}
I am implementing API pagination of 10 results at a time. I would like to be able to make a new API call for the next (or previous) 10 results when I click the arrow buttons.
The documentation refers to pageChange as an event option, but when I use the code snippet, I don't know how to utilize it. I would really appreciate any insight anyone might have on how to handle this situation.
This is a picture of the data grid button, for reference
#MaxAlex, thank you for the tip! This sent me on the right path and I finally got it working with server-side pagination. Resource
The key for me was to realize that on the onPageChange property within the DataGrid: onPageChange={(newPage) => handlePageChange(newPage)}, "newPage" was an object with the page number. I didn't need to specifically access the forward and backward arrows, but instead, just manage "newPage" in my handlePageChange function.

How to change style attribute of element with React Hooks?

Hello I have seen tutorials but not sure how to change element attributes in React like with a button click change the width of an element. This is easy with vanilla javascript using document.querySelector. But how is it done in React?? State? or useRef? It says to avoid refs too much so is there a useState way to do this? Toggling the width is my goal, but any advice is appreciated. I don't think I am supposed to use document.querySelector...
My Attempt:
const myRef = useRef("80%");
const changeWidth = () => {
widthRef.style.width = "100px";
};
<div>
<div style ={{width:400px, height: 400px}} ref ={myRef}>
<button onClick={changeWidth}></button>
</div
you can change style directly using style prop
//
const [width, setWidth] = useState("400px")
function hanldeWidthChange() {
// you can set width to any value you want
setWidth("100px")
}
<div>
<div style ={{width: width, height: "400px"}}>
<button onClick={() => hanldeWidthChange()} ></button>
</div>
</div

React accordion with correlating image outside accordion section

I can't find any examples of accordions where the active class is related to an element outside of the accordion. I'm trying to get an image to change on the side of the accordion, where each image is related to a specific object. I managed to get something working using absolute positioning, but I'm looking for a more elegant solution so I can manipulate styling better.
I can get it to work while the image is inside the accordion under the info text, but can't figure out the styling issue. I think I need to do some refactoring or do away with the array mapping to get it to work but I'm not sure.
Here is a codesandbox of more or less what I want to achieve but without the restriction of absolute positioning - https://codesandbox.io/s/ecstatic-taussig-f084t?file=/src/App.js
You can remove your img tag from your renderedItems and do something like this:
import React, { useState } from "react";
const Accordion = ({ items }) => {
const [activeIndex, setActiveIndex] = useState(0);
const onTitleClick = (index) => {
setActiveIndex(index);
};
const renderedItems = items.map((item, index) => {
const active = index === activeIndex ? "active" : "";
return (
<div key={item.title}>
<div className={`title ${active}`} onClick={() => onTitleClick(index)}>
<i className="dropdown icon"></i>
{item.title}
</div>
<div className={`content ${active}`}>
<p>{item.content}</p>
</div>
</div>
);
});
return (
<div className="container-gallery">
<div className="ui styled accordion">{renderedItems}</div>
<img
className={`content `}
src={`${items[activeIndex].image}`}
style={{
height: "200px",
width: "200px"
}}
alt="img"
/>
</div>
);
};
export default Accordion;
And for the style I don't know what you are using so I made css for the example:
.container-gallery{
display:flex;
flex-wrap:no-wrap;
justify-content: space-between;
}
here a sandBox link

Change the direction of ag-grid to RTL

I am using ag-grid in react, and I want to change the direction to RTL, also use of local text. Based on the ag-grid documentation enableRtl={true} would change the style of the grid. It is true when we set it permanently, but when I want to change it programmatically, it does not change. I passed the variable through props to the component for changing the direction and translating the text. This is my code
const Grid= ({dir}) =>{
return (
<div
className="ag-theme-balham"
style={{ height: '100%', width: '100%' }}
>
<AgGridReact
defaultColDef={defaultColDef}
columnDefs={column}
rowData={rowData}
enableRtl={dir === 'rtl'}
localeTextFunc={(key, defaultValue) => {
return dir === 'rtl' ? gridLocal[key] : defaultValue;
}}
/>
</div>
);
}
before changing direction
after changing direction
As it should be
I searched for the solution, but I cannot find a way to solve it.
What should I do? What is wrong with my code?
Edit: where I used the Grid component
const MainLayout = (props) => {
const classes = useStyles();
const theme = useTheme();
const [open, setOpen] = useState(false);
const handleDrawerOpen = () => { setOpen(true) };
const handleDrawerClose = () => { setOpen(false) };
return (
<div >
<Topbar
setLang={props.setLang}
drawerOpen={handleDrawerOpen}
drawerClose={handleDrawerClose}
status={open}
handleSignOut={props.handleSignOut}
/>
<div style={{height:'48px'}}/>
<div className={classes.content}>
<Sidebar open={open} drawerClose={handleDrawerClose}/>
<Grid dir={theme.direction}/>
</div>
</div>
);
}
I have the same issue. After searching many times, I found only one solution.
I used angular not react, but, I can tell you the steps I used to solve this problem.
I followed the following steps:
I stored the value of the direction in the localstorage
Created a button to trigger an event that will change the value of the direction.
Get the value of the direction from the localstorage in the constructor
Inside the trigger, I changed the value on the localstorage for each click event.
finally, at each click event refresh the page with window.location.reload() to see the effect.
I know. It is not the perfect solution, but this is the only solution that worked for me. I think this problem is not found in the enterprise version of ag-grid.
Update:
I found a better solution. I use angular not React.
In angular, I used <ng-template> as follow:
<ng-template [ngIf]="AgGridDir === 'rtl'" [ngIfElse]="LeftGrid" #Withbutton>
<ag-grid-angular style="width: 100%; height: 450px;"
[class]="Table_Color_mode===Constants.light || Theme_dir===Constants.light?'ag-theme-alpine':'ag-theme-alpine-dark'"
[rowData]="ItemsMainCategories | async" [columnDefs]="columnDefs" (gridReady)="OnGridReady($event)"
[defaultColDef]="defaultColDef" [overlayLoadingTemplate]="overlayLoadingTemplate" [animateRows]="true"
[enableRtl]="true" [frameworkComponents]="agFrameworks" rowSelection="single"
(rowEditingStarted)="onRowEditingStarted($event)" (cellValueChanged)="UpdateItemMainCat($event)">
</ag-grid-angular>
</ng-template>
<ng-template #LeftGrid>
<ag-grid-angular style="width: 100%; height: 450px;"
[class]="Table_Color_mode===Constants.light || Theme_dir===Constants.light?'ag-theme-alpine':'ag-theme-alpine-dark'"
[rowData]="ItemsMainCategories | async" [columnDefs]="columnDefs" (gridReady)="OnGridReady($event)"
[defaultColDef]="defaultColDef" [overlayLoadingTemplate]="overlayLoadingTemplate" [animateRows]="true"
[enableRtl]="false" [frameworkComponents]="agFrameworks" rowSelection="single"
(rowEditingStarted)="onRowEditingStarted($event)" (cellValueChanged)="UpdateItemMainCat($event)">
</ag-grid-angular>
</ng-template>
<ng-template> is a tag created by Angular framework that can be used to render some components or HTML tags based on a condition.
As you can see, I used the same Ag-grid table with the same parameters. Each one with an ng-template. I used a variable called AgGridDir which is dynamically changed to rtl to ltr based on the user choice.
If the user chooses 'rtl' the first template is rendered and the [enableRtl]="true" is set to true, and if the user chooses 'ltr', then the second template will be rendered dynamically without reloading the page and the [enableRtl]="false".
I don't know about react much details, but, I want to share the idea.

Resources