Unable to see the Tooltip while using Highlighter - reactjs

Context: I have table cell which have ellipsis, so I want to have a tooltip over the title.
Currently I am using Material UI Tooltip. Also, since there is a search option and hence I am using the highlighter react-highlight-words to highlight the search term.
Problem: When wrapping the Highlighter component with the Tooltip, the tooltip is not popping up as it does usually. I have used react-tooltip instead and it works.
Below is the code snippet of what I am trying to render :-
<TableCell align="center">
<Tooltip title={title}>
<Highlighter highlightClassName="YourHighlightClass" searchWords={[searchValue]} autoEscape textToHighlight={title} />
</Tooltip>
Seeking some help how to utilise the MUI Tooltip along with the Highlighter.
Here is the code when using react-tooltip:
<TableCell align="center">
<span data-tip={title}>
<Highlighter highlightClassName="YourHighlightClass" searchWords={[searchValue]} autoEscape textToHighlight={title} />
<ReactTooltip delayShow={500} effect="solid" border={false}/>
</span>
</TableCell>

I went through the documentation for the Tooltip and the Highlighter and found that,
Tooltip requires only one direct child, and the Highlighter renders multiple child.
Hence, the simple solution was to wrap the Highlight Component with some <span> tag, etc.
<TableCell align="center">
<Tooltip title={title}>
<span>
<Highlighter highlightClassName="YourHighlightClass" searchWords={[searchValue]} autoEscape textToHighlight={title} />
</span>
</Tooltip>
</TableCell>
Live Demo

It doesn't work because you are using a custom component that doesn't support the API that let you pass the ref down to the DOM element. The <Tooltip/> needs the child reference to know where the DOM element is so it can position itself correctly.
You can fix it by using React.forwardRef() which allow <Tooltip/> to access the children ref
const HighlightedSentence = React.forwardRef((props, ref) => {
return (
<span ref={ref} style={{ backgroundColor: "pink" }}>
<Highlighter
highlightClassName="YourHighlightClass"
searchWords={["and", "or", "the"]}
autoEscape={true}
textToHighlight="The dog is chasing the cat. Or perhaps they're just playing?"
{...props}
/>
</span>
);
});
function App() {
return (
<Tooltip title={"my tooltip"} placement="bottom">
<HighlightedSentence />
</Tooltip>
);
}
Live Demo

Related

How do I customize the MUI DataGrid footer components?

I am using the MUI V5 DataGrid component in my App and I want to customize the Footer component on the datagrid component but can't find any docs on how to go about it. This is the current default footer:
I want to achieve something resembling this:
Is there a way to reorganize the individual components and customize the styling as such? Any help is highly appreciated.
this sample code you can use for a custom footer in data grid MUI v5
first, you write your pagination component with full logic when the client clicked on the page, like this :
const RoundedPagination = () => {
return (
<Stack spacing={2}>
<Pagination
shape="rounded" page={page + 1} onChange={handleChange} count={props.numberOfPages}
renderItem={(item) => (
<PaginationItem
sx={{
color: 'main.0',
}}
components={{previous: ArrowRightRoundedIcon, next: ArrowLeftRoundedIcon}}
{...item}
/>
)}
/>
</Stack>
)
}
then you use this component in data grid like this :
<Grid container item justifyContent={'center'} alignItems={'center'} md={12}>
<DataGrid
page={page}
rows={props.dataGridValue.ROW}
columns={props.dataGridValue.COLUMNS}
autoHeight
headerHeight={52}
rowsPerPageOptions={[10]}
disableColumnMenu
Pagination
hideFooterSelectedRowCount
components={{
Pagination: RoundedPagination,
}}
/>
</Grid>
hope you get your answer good luck ;)

Autoclose bootstrap 5 Dropdown without toggle in React

I have a search field that shows data as dropdown.item when user is typing. The library is React Bootstrap (bootstrap 5). This is working great. The dropdown is showing. The problem is that the dropdown persist when clicking outside or navigating to a new link. The dropdown is in a header that does not get rerendered with the rest of the page. Using NextJS. Any tips on how to close a dropdown that has no toggle?
<form className="d-none d-sm-inline-block" style={{ zIndex: "1000" }}>
<div className="input-group input-group-navbar">
<input
type="text"
className="form-control"
placeholder="Søk"
aria-label="Search"
onChange={(event) => {
setSearchTerm(event.target.value);
}}
/>
<button className="btn" type="button">
<Icon.Search className="align-middle" />
</button>
</div>
{searchData.length >= 1 && (
<Dropdown style={{ position: "absolute", background: "white" }} autoClose="outside">
{searchData.slice(0, 10).map((element, index) => {
return (
<Link key={element.agressoResourceId} href={`employees/69918`} passHref replace={true}>
<Dropdown.Item>
{element.firstname} - {element.lastname}
</Dropdown.Item>
</Link>
);
})}
</Dropdown>
)}
</form>
The solution was to use onBlur event and hide the dropdown. The problem comes with the onblure is triggered before you press the item. The solution here was to use a setTimeout of 200ms.

Is the z-index incorrect for these radio toggles behind the Semantic-UI-React Loading component?

I'm working on a form that has Semantic-UI Radio toggles, and the loader and the toggle's appear to be loading in the wrong z-index.
I checked the css and the toggle contains the following
.ui.toggle.checkbox label:after {
z-index: 2;
}
while the loader is
.ui.dimmer {
z-index: 1000;
}
which seems like the appropriate behaviour. I want the toggles to be behind the loader to present the best user experience. Can anyone tell me if the current behaviour is by design or not? Trying to determine if this is a bug to be reported or a feature to be requested or if there's a problem with my implementation.
My code (edited for brevity)
import { Form, Dropdown, DropdownItemProps, Dimmer, Loader, Button, Icon, Segment } from "semantic-ui-react";
return (
<Fragment>
<div style={{ display: "flex", flexDirection: "column" }}>
<div className="ui segments">
<PageHeader
text="Some text"
subText="Some subtext"
pageIcon="cogs icon"
/>
</div>
<Dimmer.Dimmable dimmed={loading}>
<Dimmer simple active={loading}>
<Loader>Loading</Loader>{" "}
</Dimmer>
<Form onSubmit={() => save()}>
<Form.Checkbox
label="Label 1"
checked={display}
onChange={(e, { checked }) => setDisplay(!!checked)}
toggle
/>
<Form.Input
label="Label 2"
placeholder="Placeholder"
value={data}
onChange={(e, { value }) => setData(value)}
/>
</Form.Group>
</Form>
</Dimmer.Dimmable>
</div>
</Fragment>
);
The comment helped me out. The problem was resolved using https://coder-coder.com/z-index-isnt-working/#alternative-solution-remove-positioning-from-the-content-so-it-wont-limit-the-modals-z-index from the suggestion.
I used a sticky position for the form element. Not necessarily the best solution but it sufficed for this purpose.

How to use <br/> in string to put string in new line?

I was creating React project and here is the component that I want to ensure that is put inside a string.
<InfoIcon
tooltip={`${hints.todoHint} <br/> ${hints.inProgressHint} <br/> ${hints.doneHint}`}
/>
but it is not working since br/ is literally rendered like br/
One option is to convert tooltip in to three props and add <br /> in the InfoIcon component. For example InfoIcon component can be
const InfoIcon = ({ todoHint, inProgressHint, doneHint }) => (
<div>
{todoHint}
<br />
{inProgressHint}
<br />
{doneHint}
</div>
);
// Using Info Icon
<InfoIcon todoHint={todoHint} inProgressHint={inProgressHint} doneHint={doneHint} />
Other option is to send tooltip as follows
const tooltip = (
<div>
{hints.todoHint}
<br />
{hints.inProgressHint}
<br />
{hints.doneHint}
</div>
)
<InfoIcon tooltip={tooltip} />
Well, material-ui tooltip allows you to use ANY kind of HTML content. => refer to official document customized tooltiops
This means you can use normal <div> and <Typography />, and any other styled elements to handle multi-line content.
The only thing you need to do is pass the content to props title => refer to document of tooltip api
import {
Tooltip,
Typography
} from '#material-ui/core';
<Tooltip
title={ // customized content here via props `title`
<>
<div>Seperate line</div>
<Typography>Seperate line</Typography>
</>
}
>
<IconButton aria-label="delete">
<InfoIcon /> // You can use your original icon here
</IconButton>
</Tooltip>
Watch it online: https://stackblitz.com/run
You can find related question here: How to make line break for ToolTip titles in Material-UI

how to visible tooltip always in react slider

I am using react slider with tooltip.
<Slider
min={ set_min(this.state.myValue) }
max={ set_max(this.state.myValue) }
defaultValue={ set_def(this.state.myValue) }
handle={handle}
toolTipVisibleAlways = {true}
/>
<Tooltip
className = "tooltip-custom"
prefixCls="rc-slider-tooltip"
overlay={percentFormatter(value, this.state.myValue) }
visible={dragging}
placement="top"
key={index}
delayShow = {300}
delayHide = {150}
>
<Handle value={value} {...restProps} />
</Tooltip>
all things are good and well-displayed.
what i want to know is that how can i make tooltip always visible.
I searched this answer on the internet and found two answers.
first one is toolTipVisibleAlways = {true}
and second one is
delayShow = {300}
delayHide = {150}
But as you can see my code, nothing changed.
Use tipProps props exposed after Slider wrapped by createSliderWithTooltip. Example below should work as tipProps will pass the props to rc-tooltip component.
Read here for detailed explanation and also see this example provided by rc-slider
.
<Slider
min={ set_min(this.state.myValue) }
max={ set_max(this.state.myValue) }
defaultValue={ set_def(this.state.myValue) }
handle={handle}
tipProps={{visible:true}}
/>
I solved this issue by making my own inside the handle. This way the text will always move with the handle.
<SliderTooltip
prefixCls="rc-slider-tooltip"
visible={dragging}
placement="top"
key={index}
defaultVisible={true}
visible={true}
align={{
offset: [0, -5],
}}
>
<Handle value={value} {...restProps}>
<span>{value}</span>
</Handle>
</SliderTooltip>

Resources