I have the following two blocks of code generated from React Material UI both contained within a larger React element written by myself.
<InputAdornment muiFormControl={{...}} position="end" classes={{...}} component="div" disablePointerEvents={false} disableTypography={false}>
<div className="MuiInputAdornment-root-35 MuiInputAdornment-positionEnd-38 Hook-searchFieldInputAdornmentStyle-1adbbdv">
<pure(SearchIcon)>
<SearchIcon>
<WithStyles(SvgIcon)>
<SvgIcon classes={{...}} color="inherit" component="svg" fontSize="default" viewBox="0 0 24 24">
<svg className="MuiSvgIcon-root-40" focusable="false" viewBox="0 0 24 24" color={[undefined]} aria-hidden="true" role="presentation">
<path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" />
<path fill="none" d="M0 0h24v24H0z" />
</svg>
</SvgIcon>
</WithStyles(SvgIcon)>
</SearchIcon>
</pure(SearchIcon)>
</div>
</InputAdornment>
and
<InputAdornment muiFormControl={{...}} position="end" classes={{...}} component="div" disablePointerEvents={false} disableTypography={false}>
<div className="MuiInputAdornment-root-35 MuiInputAdornment-positionEnd-38">
<pure(ExpandLessIcon)>
<ExpandLessIcon>
<WithStyles(SvgIcon)>
<SvgIcon classes={{...}} color="inherit" component="svg" fontSize="default" viewBox="0 0 24 24">
<svg className="MuiSvgIcon-root-40" focusable="false" viewBox="0 0 24 24" color={[undefined]} aria-hidden="true" role="presentation">
<path d="M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z" />
<path fill="none" d="M0 0h24v24H0z" />
</svg>
</SvgIcon>
</WithStyles(SvgIcon)>
</ExpandLessIcon>
</pure(ExpandLessIcon)>
</div>
</InputAdornment>
The only important difference is that one has a SearchIcon contained in it and the other has an ExpandLessIcon
I want to find the one with the SearchIcon using Enzyme. I have the following so far
wrapper.find(InputAdornment).containsNode(SearchIcon) but it gives me the following error
ReferenceError: SearchIcon is not defined
I should add that SearchIcon is not a component of mine and is dynamically generated by material-ui so I can't reference its type.
Any idea how I should adjust my enzyme query ?
.containsNode() needs a React Element like <div />, not React Component like div.
You can use a displayName in find, e.g. to get the SearchIcon element:
expect(wrapper.find(InputAdornment).find('SearchIcon')).toHaveLength(1)
or the InputAdornment containing SearchIcon:
expect(
wrapper.find(InputAdornment).filterWhere(x => x.find('SearchIcon').exists())
).toHaveLength(1)
Related
I have a header with Logo, on left side, page title - in the middle, and user menu, on the right. Currently I'm displaying a SVG next to each page title. For example, on page /organizations I display this:
After that I've added a SVG that shows when I hover on the element (it's the same SVG, but filled)
How could I make transition between these two smooth? I'm using Tailwind for styling and tried adding transition-all to almost every class but that sadly didn't work.
This is the code responsible for switching between the SVGs:
const [hover, setHover] = React.useState(false);
const handleMouseOver = () => {
setHover(true);
};
const handleMouseLeave = () => {
setHover(false);
};
return (
...
<div className="w-1/2 flex justify-center">
<Link
to={getModuleInfo(pathname, t, organization).url}
className="max-w-fit flex items-center gap-2"
prefetch="intent"
>
<div
className="flex items-center gap-2"
onMouseOver={handleMouseOver}
onMouseLeave={handleMouseLeave}
>
<>
{hover
? getModuleInfo(pathname, t, organization).logoHover
: getModuleInfo(pathname, t, organization).logo}
</>
<h5 className="organizations text-md md:text-2xl font-sans font-normal text-center text-colublue-500">
{getModuleInfo(pathname, t, organization).title}
</h5>
</div>
</Link>
</div>
...
)
UPD: to make things more clear, these would be 2 SVG examples that I would like to transition between:
And this are the <svg> for them:
// Unfilled SVG
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.41421 2.58579C8.78929 2.21071 9.29799 2 9.82843 2H18C18.5304 2 19.0391 2.21071 19.4142 2.58579C19.7893 2.96086 20 3.46957 20 4V20C20 20.5304 19.7893 21.0391 19.4142 21.4142C19.0391 21.7893 18.5304 22 18 22H6C5.46957 22 4.96086 21.7893 4.58579 21.4142C4.21071 21.0391 4 20.5304 4 20V7.82843C4 7.29799 4.21071 6.78929 4.58579 6.41421L8.41421 2.58579Z" stroke="#052141" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10 2V7C10 7.55228 9.55228 8 9 8H4.5" stroke="#052141" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
// Filled SVG
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.82843 1C9.03278 1 8.26972 1.31607 7.70711 1.87868L3.87868 5.70711C3.31607 6.26972 3 7.03278 3 7.82843V20C3 20.7957 3.31607 21.5587 3.87868 22.1213C4.44129 22.6839 5.20435 23 6 23H18C18.7956 23 19.5587 22.6839 20.1213 22.1213C20.6839 21.5587 21 20.7957 21 20V4C21 3.20435 20.6839 2.44129 20.1213 1.87868C19.5587 1.31607 18.7956 1 18 1H9.82843ZM16.7071 9.29289C17.0976 9.68342 17.0976 10.3166 16.7071 10.7071L11.3738 16.0404C10.9832 16.431 10.3501 16.431 9.95956 16.0404L7.29289 13.3738C6.90237 12.9832 6.90237 12.3501 7.29289 11.9596C7.68342 11.569 8.31658 11.569 8.70711 11.9596L10.6667 13.9191L15.2929 9.29289C15.6834 8.90237 16.3166 8.90237 16.7071 9.29289Z" fill="#052141"/>
</svg>
With plain CSS and SVG, you can do this with opacity and transition.
.filled {
opacity: 0;
transition: opacity 0.3s;
}
svg:hover .filled {
opacity: 1;
}
<svg width="96" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.41421 2.58579C8.78929 2.21071 9.29799 2 9.82843 2H18C18.5304 2 19.0391 2.21071 19.4142 2.58579C19.7893 2.96086 20 3.46957 20 4V20C20 20.5304 19.7893 21.0391 19.4142 21.4142C19.0391 21.7893 18.5304 22 18 22H6C5.46957 22 4.96086 21.7893 4.58579 21.4142C4.21071 21.0391 4 20.5304 4 20V7.82843C4 7.29799 4.21071 6.78929 4.58579 6.41421L8.41421 2.58579Z" stroke="#052141" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10 2V7C10 7.55228 9.55228 8 9 8H4.5" stroke="#052141" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path class="filled" d="M9.82843 1C9.03278 1 8.26972 1.31607 7.70711 1.87868L3.87868 5.70711C3.31607 6.26972 3 7.03278 3 7.82843V20C3 20.7957 3.31607 21.5587 3.87868 22.1213C4.44129 22.6839 5.20435 23 6 23H18C18.7956 23 19.5587 22.6839 20.1213 22.1213C20.6839 21.5587 21 20.7957 21 20V4C21 3.20435 20.6839 2.44129 20.1213 1.87868C19.5587 1.31607 18.7956 1 18 1H9.82843ZM16.7071 9.29289C17.0976 9.68342 17.0976 10.3166 16.7071 10.7071L11.3738 16.0404C10.9832 16.431 10.3501 16.431 9.95956 16.0404L7.29289 13.3738C6.90237 12.9832 6.90237 12.3501 7.29289 11.9596C7.68342 11.569 8.31658 11.569 8.70711 11.9596L10.6667 13.9191L15.2929 9.29289C15.6834 8.90237 16.3166 8.90237 16.7071 9.29289Z" fill="#052141"/>
</svg>
You could also use css variables to transition between the design states.
Similar to #ksav's this approach will also need to combine both svgs.
This way we can render the icon with more design variations.
let icon = document.querySelector('.iconTrans');
function toggleState() {
icon.classList.toggle('active')
}
svg {
border: 1px solid #ccc;
overflow: visible;
width: 10em;
}
svg path {
transition: 1s;
}
.iconTrans {
--strokeColor: #052141;
--strokeWidth: 2px;
--opacity1: 1;
--opacity2: 0;
--fillColor: #052141;
}
.active {
--strokeColor: #052141;
--strokeWidth: 0px;
--opacity1: 0;
--opacity2: 1;
--fillColor: #ccc;
}
<p><button id="btnToggle" onclick="toggleState()">Toggle state</button></p>
<svg class="iconTrans" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path class="paper" d="M8.41421 2.58579C8.78929 2.21071 9.29799 2 9.82843 2H18C18.5304 2 19.0391 2.21071 19.4142 2.58579C19.7893 2.96086 20 3.46957 20 4V20C20 20.5304 19.7893 21.0391 19.4142 21.4142C19.0391 21.7893 18.5304 22 18 22H6C5.46957 22 4.96086 21.7893 4.58579 21.4142C4.21071 21.0391 4 20.5304 4 20V7.82843C4 7.29799 4.21071 6.78929 4.58579 6.41421L8.41421 2.58579Z
M10 2V7C10 7.55228 9.55228 8 9 8H4.5" style="stroke:var(--strokeColor); stroke-width:var(--strokeWidth); opacity:var(--opacity1)" stroke-linecap="round" stroke-linejoin="round" />
<path class="paperCheck" d="M9.82843 1C9.03278 1 8.26972 1.31607 7.70711 1.87868L3.87868 5.70711C3.31607 6.26972 3 7.03278 3 7.82843V20C3 20.7957 3.31607 21.5587 3.87868 22.1213C4.44129 22.6839 5.20435 23 6 23H18C18.7956 23 19.5587 22.6839 20.1213 22.1213C20.6839 21.5587 21 20.7957 21 20V4C21 3.20435 20.6839 2.44129 20.1213 1.87868C19.5587 1.31607 18.7956 1 18 1H9.82843Z
M16.7071 9.29289C17.0976 9.68342 17.0976 10.3166 16.7071 10.7071L11.3738 16.0404C10.9832 16.431 10.3501 16.431 9.95956 16.0404L7.29289 13.3738C6.90237 12.9832 6.90237 12.3501 7.29289 11.9596C7.68342 11.569 8.31658 11.569 8.70711 11.9596L10.6667 13.9191L15.2929 9.29289C15.6834 8.90237 16.3166 8.90237 16.7071 9.29289Z" style="fill:var(--fillColor); opacity:var(--opacity2); " />
</svg>
This is the way I did , but I got "Uncaught RangeError: Maximum call stack size exceeded"
function get_tag_elem() {
let class_name = add_tag();
let tag_elem = $('#meta_tag_element > button.bx--tag.bx--tag--color');
tag_elem.removeClass('bx--tag--color');
tag_elem.addClass(class_name);
let tag_html = tag_elem.html()
return $(tag_html);
}
<button id="tag_value" class="bx--tag">
<span class="bx--tag__label">Article Tag</span>
<svg focusable="false" preserveAspectRatio="xMidYMid meet" style="will-change: transform;" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" aria-hidden="true">
<path d="M12 4.7L11.3 4 8 7.3 4.7 4 4 4.7 7.3 8 4 11.3 4.7 12 8 8.7 11.3 12 12 11.3 8.7 8z"></path>
</svg>
</button>
The idea is to duplicate the button using an HTML template.
var template = document.getElementById("tag_value").outerHTML;
var container = document.getElementById("container")
var id = 0;
function add_button() {
$(container).append($(template.replace("tag_value", "btn" + ++id)))
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span style="display:none">
<button id="tag_value" class="bx--tag">
<span class="bx--tag__label">Article Tag</span>
<svg focusable="false" preserveAspectRatio="xMidYMid meet" style="will-change: transform;" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" aria-hidden="true">
<path d="M12 4.7L11.3 4 8 7.3 4.7 4 4 4.7 7.3 8 4 11.3 4.7 12 8 8.7 11.3 12 12 11.3 8.7 8z"></path>
</svg>
</button>
</span>
<button onclick="add_button()">add button</button>
<div id="container"></div>
Im getting this error here:
<a data-toggle="collapse" aria-expanded="true" className="dropdown-toggle autodropdown">
<NavLink
to="/"
>
<div >
<svg xmlns="http://www.w3.org/2000/svg" width={24} height={24} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" className="feather feather-home"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" /><polyline points="9 22 9 12 15 12 15 22" /></svg>
<span>home</span>
</div>
</NavLink>
</a>
I'm new to React, How can I fix this?
use NavLink or <a> because NavLink also a <a> tag, so using NavLink inside doesn't make sense here.
I have one common component for which I want to change its color property to use it at other place.
const ViewAllIcon = (props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="18"
height="18"
viewBox="0 0 26 27"
{...props}
>
<path
fill="var(--primary)"
d="M13 0C5.832 0 0 5.86 0 13.061c0 7.202 5.832 13.062 13 13.062s13-5.86 13-13.062C26 5.86 20.168 0 13 0z"
/>
<path
fill="#FFF"
d="M14.764 13.061l-4.437-4.726c-.48-.512-.48-1.344 0-1.856s1.261-.512 1.742 0l5.357 5.708c.454.483.454 1.266 0 1.749l-5.357 5.707c-.48.512-1.261.512-1.742 0-.48-.512-.48-1.343 0-1.855l4.437-4.727z"
/>
</svg>
);
export default ViewAllIcon;
This is common component having primary blue and white color.
<ViewAllIcon className="ml8" fill="white" />
I am using it to change the fill color to white and green.
change fill value to "currentColor" and than pass color var to component.
ViewAllIcon({ color: 'var(--primary)' })
or
<ViewAllIcon color={'var(--primary)'} />
const ViewAllIcon = (props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="18"
height="18"
viewBox="0 0 26 27"
{...props}
>
<path
fill="currentColor"
d="M13 0C5.832 0 0 5.86 0 13.061c0 7.202 5.832 13.062 13 13.062s13-5.86 13-13.062C26 5.86 20.168 0 13 0z"
/>
<path
fill="currentColor"
d="M14.764 13.061l-4.437-4.726c-.48-.512-.48-1.344 0-1.856s1.261-.512 1.742 0l5.357 5.708c.454.483.454 1.266 0 1.749l-5.357 5.707c-.48.512-1.261.512-1.742 0-.48-.512-.48-1.343 0-1.855l4.437-4.727z"
/>
</svg>
);
export default ViewAllIcon;
You could put the props directly to fill attribute
Something like this:
const ViewAllIcon = (props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="18"
height="18"
viewBox="0 0 26 27"
{...props}
>
<path
fill={props.fill} // <--- UPDATE HERE!
d="M13 0C5.832 0 0 5.86 0 13.061c0 7.202 5.832 13.062 13 13.062s13-5.86 13-13.062C26 5.86 20.168 0 13 0z"
/>
<path
fill="#FFF"
d="M14.764 13.061l-4.437-4.726c-.48-.512-.48-1.344 0-1.856s1.261-.512 1.742 0l5.357 5.708c.454.483.454 1.266 0 1.749l-5.357 5.707c-.48.512-1.261.512-1.742 0-.48-.512-.48-1.343 0-1.855l4.437-4.727z"
/>
</svg>
);
export default ViewAllIcon;
Working Example:
I have this SVG:
<svg style="fill:#1780df; color: #1780df; " xmlns="http://www.w3.org/2000/svg" width=".8em"
height=".8em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round" class="feather feather-star"
data-v-41e50536="" data-v-50fd7d5a="">
<polygon
points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91
8.26 12 2"
data-v-41e50536="" data-v-50fd7d5a=""></polygon>
</svg>
This is a blue star. I want to do add an arbitrary number of these stars to an existing div using JavaScript.
How could I do it?
Update :
This is the existing div (it already has five stars and a short paragraph):
<div class="stars-real-container" id="dsc1">
<svg style="fill:#1780df; color: #1780df; margin-right: 6px; "
xmlns="http://www.w3.org/2000/svg" width=".8em" height=".8em" viewBox="0 0 24 24"
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round" class="feather feather-star" data-v-41e50536=""
data-v-50fd7d5a="">
<polygon
points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"
data-v-41e50536="" data-v-50fd7d5a=""></polygon>
</svg>
<svg style="fill:#1780df; color: #1780df; " xmlns="http://www.w3.org/2000/svg" width=".8em"
height=".8em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round" class="feather feather-star"
data-v-41e50536="" data-v-50fd7d5a="">
<polygon
points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"
data-v-41e50536="" data-v-50fd7d5a=""></polygon>
</svg>
<svg style="fill:#1780df; color: #1780df; " xmlns="http://www.w3.org/2000/svg" width=".8em"
height=".8em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round" class="feather feather-star"
data-v-41e50536="" data-v-50fd7d5a="">
<polygon
points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"
data-v-41e50536="" data-v-50fd7d5a=""></polygon>
</svg>
<svg style="fill:#1780df; color: #1780df; " xmlns="http://www.w3.org/2000/svg" width=".8em"
height=".8em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round" class="feather feather-star"
data-v-41e50536="" data-v-50fd7d5a="">
<polygon
points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"
data-v-41e50536="" data-v-50fd7d5a=""></polygon>
</svg>
<svg style="fill:#1780df; color: #1780df; " xmlns="http://www.w3.org/2000/svg" width=".8em"
height=".8em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round" class="feather feather-star"
data-v-41e50536="" data-v-50fd7d5a="">
<polygon
points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"
data-v-41e50536="" data-v-50fd7d5a=""></polygon>
</svg>
<p class="number-of-comments" id="dc1">(۱۲ نظر )</p>
</div>
Its CSS:
.stars-real-container {
height: 100%;
width: 50%;
display: flex;
flex-direction: row-reverse;
justify-content: space-around;
}
The idea is to have stars to show the popularity of something. I have not ever created SVG elements with JavaScript. I checked several other stackoverflow threads like This. But it was a simple SVG.
There are many options to do that. The easiest way is this one in my opinion.
Updated code:
document.querySelector('.stars-real-container').innerHTML = '<svg style="fill:#1780df; color: #1780df; " xmlns="http://www.w3.org/2000/svg" width=".8em" height=".8em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" lass="feather feather-star" data-v-41e50536="" data-v-50fd7d5a=""><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" data-v-41e50536="" data-v-50fd7d5a=""></polygon></svg>' + document.querySelector('.stars-real-container').innerHTML;
To keep your paragraph as the last-child, you have to put the svg as first child and then add the existing content (+ document.querySelector('.stars-real-container').innerHTML)
This is a "deliberate" solution example where I clone the "star". Might be better ways but this is one way. Note I put the color of the star in CSS to illustrate how to do that also - could be done by using classes to provide a value fo the currentColor. I made mine more "pink" :)
Note I went with the "clone" approach so I could put the svg element in the HTML and not have to muck with string constants for the SVG, harder to maintain etc.
let howMany = 4;
let prettystar = document.getElementById("star-container").querySelector('svg');
let targetElement = document.querySelector("#star-target").querySelector('.star-me');
for (let step = 0; step < howMany; step++) {
let pclone = prettystar.cloneNode(true);
console.log(step)
targetElement.appendChild(pclone);
}
.star-me {
color: #df80df;
}
#star-container {
display: none;
}
<div id="star-container">
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width=".8em" height=".8em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-star" data-v-41e50536=""
data-v-50fd7d5a="">
<polygon
points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91
8.26 12 2"
data-v-41e50536="" data-v-50fd7d5a=""></polygon></svg>
</div>
<div id="star-target"><span>Please make me a star!</span>
<span class="star-me"></span>
</div>