Skip to content

Commit

Permalink
Multiselect mode in <Dropdown> component (#354)
Browse files Browse the repository at this point in the history
  • Loading branch information
sahariko authored Dec 1, 2021
1 parent e0f3b8f commit c0a1736
Show file tree
Hide file tree
Showing 28 changed files with 852 additions and 253 deletions.
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 @@ -380,6 +380,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

0 comments on commit c0a1736

Please sign in to comment.