Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiselect component #354

Merged
merged 14 commits into from
Dec 1, 2021
55 changes: 46 additions & 9 deletions src/components/Chips/Chips.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,54 @@ import { elementColorsNames, getElementColor } from "../../general-stories/color
import "./Chips.scss";

const Chips = forwardRef(
({ className, id, label, leftIcon, rightIcon, disabled, readOnly, color, iconSize, onDelete }, ref) => {
(
{
className,
id,
label,
leftIcon,
rightIcon,
disabled,
readOnly,
color,
iconSize,
onDelete,
onMouseDown,
noAnimation,
"data-testid": dataTestId
},
ref
) => {
const componentRef = useRef(null);
const mergedRef = useMergeRefs({ refs: [ref, componentRef] });

const backgroundColorStyle = useMemo(() => {
return { backgroundColor: disabled ? getCSSVar("disabled-background-color") : getElementColor(color, true) };
}, [disabled, color]);

const onDeleteCallback = useCallback(() => {
if (onDelete) {
onDelete(id);
}
}, [id, onDelete]);
const onDeleteCallback = useCallback(
e => {
if (onDelete) {
onDelete(id, e);
}
},
[id, onDelete]
);

const hasCloseButton = !readOnly && !disabled;

return (
<div
ref={mergedRef}
className={cx("chips--wrapper", className, { disabled, "with-close": hasCloseButton })}
className={cx("chips--wrapper", className, {
disabled,
"with-close": hasCloseButton,
"no-animation": noAnimation
})}
id={id}
style={backgroundColorStyle}
onMouseDown={onMouseDown}
data-testid={dataTestId}
>
{leftIcon ? (
<Icon
Expand Down Expand Up @@ -63,6 +89,7 @@ const Chips = forwardRef(
icon={CloseSmall}
iconSize={18}
onClick={onDeleteCallback}
data-testid={`${dataTestId}-close`}
/>
)}
</div>
Expand All @@ -85,7 +112,15 @@ Chips.propTypes = {
color: PropTypes.oneOf(Object.keys(Chips.colors)),
/** size for font icon */
iconSize: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
onDelete: PropTypes.func
onDelete: PropTypes.func,
/**
* Disables the Chips's entry animation
*/
noAnimation: PropTypes.bool,
/**
* Callback function to be called when the user clicks the component.
*/
onMouseDown: PropTypes.func
};
Chips.defaultProps = {
className: "",
Expand All @@ -97,7 +132,9 @@ Chips.defaultProps = {
leftIcon: null,
color: Chips.colors.PRIMARY,
iconSize: 16,
onDelete: NOOP
onDelete: NOOP,
onMouseDown: NOOP,
noAnimation: false
};

export default Chips;
6 changes: 5 additions & 1 deletion src/components/Chips/Chips.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
$icon-margin: 4px;

.chips--wrapper {
display: flex;
display: inline-flex;
overflow: hidden;
height: 24px;
border-radius: 4px;
Expand All @@ -16,6 +16,10 @@ $icon-margin: 4px;
animation: chips-enter 100ms;
animation-timing-function: cubic-bezier(0, 0, 0.35, 1);

&.no-animation {
animation: none;
}

&.with-close {
padding-right: 4px;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ exports[`renders correctly with empty props 1`] = `
<div
className="chips--wrapper with-close"
id=""
onMouseDown={[Function]}
style={
Object {
"backgroundColor": "var(--primary-selected-color)",
Expand All @@ -18,6 +19,7 @@ exports[`renders correctly with empty props 1`] = `
<svg
aria-hidden={false}
className="icon_component chip-icon close icon_component--clickable"
data-testid="undefined-close"
fill="currentColor"
height="18"
onClick={[Function]}
Expand Down
66 changes: 50 additions & 16 deletions src/components/Counter/Counter.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,22 @@ import useEventListener from "../../hooks/useEventListener";
import useAfterFirstRender from "../../hooks/useAfterFirstRender";

import "./Counter.scss";

const Counter = ({ count, size, kind, color, wrapperClassName, maxDigits, ariaLabeledBy, ariaLabel, id, prefix }) => {
import { NOOP } from "../../utils/function-utils";

const Counter = ({
count,
size,
kind,
color,
wrapperClassName,
maxDigits,
ariaLabeledBy,
ariaLabel,
id,
prefix,
onMouseDown,
noAnimation
}) => {
// State
const [countChangeAnimationState, setCountChangeAnimationState] = useState(false);

Expand Down Expand Up @@ -67,21 +81,31 @@ const Counter = ({ count, size, kind, color, wrapperClassName, maxDigits, ariaLa
}, [size, kind, color, countChangeAnimationState]);

const countText = count?.toString().length > maxDigits ? `${10 ** maxDigits - 1}+` : count;
const counter = <span id={`counter-${id}`}>{prefix + countText}</span>;

return (
<span className={wrapperClassName} aria-label={`${ariaLabel} ${countText}`} aria-labelledby={ariaLabeledBy}>
<span
className={wrapperClassName}
aria-label={`${ariaLabel} ${countText}`}
aria-labelledby={ariaLabeledBy}
onMouseDown={onMouseDown}
>
<div className={classNames} aria-label={countText} ref={ref}>
<SwitchTransition mode="out-in">
<CSSTransition
classNames="monday-style-counter--fade"
addEndListener={(node, done) => {
node.addEventListener("transitionend", done, false);
}}
key={countText}
>
<span id={`counter-${id}`}>{prefix + countText}</span>
</CSSTransition>
</SwitchTransition>
{noAnimation ? (
counter
) : (
<SwitchTransition mode="out-in">
<CSSTransition
classNames="monday-style-counter--fade"
addEndListener={(node, done) => {
node.addEventListener("transitionend", done, false);
}}
key={countText}
>
<span id={`counter-${id}`}>{prefix + countText}</span>
</CSSTransition>
</SwitchTransition>
)}
</div>
</span>
);
Expand All @@ -105,7 +129,15 @@ Counter.propTypes = {
kind: PropTypes.oneOf([Counter.kinds.FILL, Counter.kinds.LINE]),
/** maximum number of digits to display (see relevant story) */
maxDigits: PropTypes.number,
prefix: PropTypes.string
prefix: PropTypes.string,
/**
* Callback to be called when the counter is clicked.
*/
onMouseDown: PropTypes.func,
/**
* Disables the component's animation.
*/
noAnimation: PropTypes.bool
};
Counter.defaultProps = {
id: "",
Expand All @@ -117,7 +149,9 @@ Counter.defaultProps = {
maxDigits: 3,
ariaLabeledBy: "",
ariaLabel: "",
prefix: ""
prefix: "",
onMouseDown: NOOP,
noAnimation: false
};

export default Counter;
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ exports[`Snapshots renders correctly with count above limit 1`] = `
aria-label=" 999+"
aria-labelledby=""
className=""
onMouseDown={[Function]}
>
<div
aria-label="999+"
Expand All @@ -24,6 +25,7 @@ exports[`Snapshots renders correctly with count below the limit 1`] = `
aria-label=" 1"
aria-labelledby=""
className=""
onMouseDown={[Function]}
>
<div
aria-label={1}
Expand All @@ -43,6 +45,7 @@ exports[`Snapshots renders correctly with the prefix 1`] = `
aria-label=" 13"
aria-labelledby=""
className=""
onMouseDown={[Function]}
>
<div
aria-label={13}
Expand Down
1 change: 1 addition & 0 deletions src/components/Dialog/Dialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ export default class Dialog extends PureComponent {
styleObject={style}
ref={ref}
onClick={this.onContentClick}
hasTooltip={!!tooltip}
>
{contentRendered}
{tooltip && (
Expand Down
26 changes: 26 additions & 0 deletions src/components/Dialog/Dialog.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,32 @@
@import "../../styles/themes.scss";

$arrow-size: 12px;

.dialog-node {
position: absolute;
top: 0;
height: 0;
z-index: 100000;
}

.monday-style-tooltip-arrow {
width: $arrow-size;
height: $arrow-size;
position: absolute;
border-radius: 2px;

background-color: $white-theme-bg-color;

&[data-placement*="bottom"] {
top: 1px;
}
&[data-placement*="top"] {
bottom: 1px;
}
&[data-placement*="left"] {
right: 1px;
}
&[data-placement*="right"] {
left: 1px;
}
}
6 changes: 4 additions & 2 deletions src/components/Dialog/DialogContent/DialogContent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ export const DialogContent = React.forwardRef(
onClick = NOOP,
showDelay,
styleObject = EMPTY_OBJECT,
isReferenceHidden
isReferenceHidden,
hasTooltip = false
},
forwardRef
) => {
Expand Down Expand Up @@ -60,7 +61,8 @@ export const DialogContent = React.forwardRef(
<CSSTransition {...transitionOptions} in={isOpen} appear={!!animationType} timeout={showDelay}>
<div
className={classNames("monday-style-dialog-content-component", position, {
[`edge-${startingEdge}`]: startingEdge
[`edge-${startingEdge}`]: startingEdge,
"has-tooltip": hasTooltip
})}
ref={ref}
>
Expand Down
16 changes: 12 additions & 4 deletions src/components/Dialog/DialogContent/DialogContent.scss
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
@import "../../../styles/themes.scss";



.monday-style-dialog-content-wrapper {
outline: 0;

&[data-popper-reference-hidden='true']{
&[data-popper-reference-hidden="true"] {
visibility: hidden;
pointer-events: none;
}
Expand Down Expand Up @@ -122,7 +120,17 @@
&.right-end,
&.left,
&.left-start,
&.left-end{
&.left-end {
transform: scale(1);
}
}

.monday-style-dialog-content-component {
&:focus {
outline: none;
}

&.has-tooltip {
padding: 6px;
}
}
Loading