Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Issue #45 #98

Merged
merged 4 commits into from
Feb 17, 2021
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 102 additions & 62 deletions src/components/SkillsList/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* Shows list of skills with "N more" link which is showing tooltip with a full list of skills.
*/
import React, { useCallback, useState, useMemo } from "react";
import React, { useCallback, useState, useMemo, useEffect } from "react";
import PT from "prop-types";
import _ from "lodash";
import "./styles.module.scss";
Expand All @@ -19,6 +19,9 @@ const SkillsList = ({ requiredSkills, skills, limit = 3 }) => {
// if has requiredSkills, show two columns, eles show only one column
const showMatches = !!requiredSkills;
const [isOpen, setIsOpen] = useState(false);
const [isDelayClose, setIsDelayClose] = useState(false);
const [isPopoverEnter, setIsPopoverEnter] = useState(false);
const [timeId, setTimeId] = useState(null);
const [referenceElement, setReferenceElement] = useState(null);
const [popperElement, setPopperElement] = useState(null);

Expand Down Expand Up @@ -58,82 +61,119 @@ const SkillsList = ({ requiredSkills, skills, limit = 3 }) => {
],
});

const close = useCallback(() => {
setIsOpen(false);
}, [setIsOpen]);
useEffect(() => {
if (isDelayClose) {
const timer = setTimeout(() => {
if (!isPopoverEnter) {
setIsOpen(false);
setIsDelayClose(false);
setIsPopoverEnter(false);
}
}, 1000);
return () => clearTimeout(timer);
}
}, [isDelayClose, isPopoverEnter]);

const delayClose = useCallback(
(evt) => {
setIsDelayClose(true);
},
[setIsDelayClose]
);
const close = useCallback(
(evt) => {
setIsOpen(false);
setIsDelayClose(false);
setIsPopoverEnter(false);
},
[setIsOpen]
);

const open = useCallback(() => {
setIsOpen(true);
setIsDelayClose(false);
}, [setIsOpen]);

const toggle = useCallback(() => {
setIsOpen(!isOpen);
}, [isOpen, setIsOpen]);

const enterPopover = useCallback(() => {
setIsPopoverEnter(true);
}, [setIsPopoverEnter]);

const leavePopover = useCallback(() => {
setIsOpen(false);
setIsDelayClose(false);
setIsPopoverEnter(false);
}, [setIsPopoverEnter]);

return (
<div styleName="skills-list">
{_.map(skillsToShow, "name").join(", ")}
{skillsToHide.length > 0 && (
<OutsideClickHandler onOutsideClick={close} display="inline">
<div
styleName="skills-list"
onClick={toggle}
onMouseEnter={open}
onMouseLeave={delayClose}
role="button"
tabIndex={0}
ref={setReferenceElement}
>
{_.map(skillsToShow, "name").join(", ")}

{skillsToHide.length > 0 && (
<>
{" and "}
<span styleName="more">{skillsToHide.length > 0} more</span>
</>
)}
<>
{" and "}
<OutsideClickHandler onOutsideClick={close} display="inline">
<span
styleName="more"
onClick={toggle}
onMouseEnter={open}
onMouseLeave={close}
role="button"
tabIndex={0}
ref={setReferenceElement}
{isOpen && (
<div
styleName="popover"
ref={setPopperElement}
onMouseEnter={enterPopover}
onMouseLeave={leavePopover}
style={styles.popper}
{...attributes.popper}
>
{skillsToHide.length > 0} more
</span>

{isOpen && (
<div
styleName="popover"
ref={setPopperElement}
style={styles.popper}
{...attributes.popper}
>
<div styleName="popover-content">
{requiredSkills && (
<div styleName="skills-section">
<div styleName="skills-title">Required Job Skills</div>
<ul styleName="skills-list">
{!requiredSkills.length && <li>None</li>}
{requiredSkills.map((skill) => (
<li key={skill.id}>
{_.find(skills, { id: skill.id }) ? (
<IconCheck />
) : (
<IconCross />
)}{" "}
{skill.name}
</li>
))}
</ul>
</div>
)}
{otherSkills && (
<div styleName="skills-section">
<div styleName="skills-title">
{showMatches ? "Other User Skills" : "Required Skills"}
</div>
<ul styleName="skills-list">
{otherSkills.map((skill) => (
<li key={skill.id}>{skill.name}</li>
))}
</ul>
<div styleName="popover-content">
{requiredSkills && (
<div styleName="skills-section">
<div styleName="skills-title">Required Job Skills</div>
<ul styleName="skills-list">
{!requiredSkills.length && <li>None</li>}
{requiredSkills.map((skill) => (
<li key={skill.id}>
{_.find(skills, { id: skill.id }) ? (
<IconCheck />
) : (
<IconCross />
)}{" "}
{skill.name}
</li>
))}
</ul>
</div>
)}
{otherSkills && (
<div styleName="skills-section">
<div styleName="skills-title">
{showMatches ? "Other User Skills" : "Required Skills"}
</div>
)}
</div>
<ul styleName="skills-list">
{otherSkills.map((skill) => (
<li key={skill.id}>{skill.name}</li>
))}
</ul>
</div>
)}
</div>
)}
</OutsideClickHandler>
</div>
)}
</>
)}
</div>
</div>
</OutsideClickHandler>
);
};

Expand Down