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

V2 Multi-select (Team Select) #4324

Merged
merged 16 commits into from
Sep 10, 2022
Merged
16 changes: 14 additions & 2 deletions apps/storybook/stories/Select.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
import { ComponentMeta } from "@storybook/react";

import { Select } from "@calcom/ui/v2";
import MultiDropdownSelect from "@calcom/ui/v2/modules/event-types/MultiDropdownSelect";

export default {
title: "Form/Select",
component: Select,
} as ComponentMeta<typeof Select>;

const testOptions = [
const singleOptions = [
{
label: "Select",
value: 0,
},
...[5, 10, 15, 20, 30, 45, 60, 90, 120].map((minutes) => ({
label: minutes + " " + "minutes",
value: minutes,
})),
];
const multiOptions = [
{
label: "Select",
value: 0,
Expand All @@ -18,4 +29,5 @@ const testOptions = [
})),
];

export const Single = () => <Select options={testOptions} />;
export const Single = () => <Select options={singleOptions} />;
export const Multi = () => <MultiDropdownSelect options={multiOptions} />;
113 changes: 113 additions & 0 deletions packages/ui/v2/modules/event-types/MultiDropdownSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import autoAnimate from "@formkit/auto-animate";
import React, { useEffect, useRef } from "react";
import { components, GroupBase, Props, ValueContainerProps } from "react-select";

import { Icon } from "@calcom/ui/Icon";

// import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Select } from "../..";

const LimitedChipsContainer = <Option, IsMulti extends boolean, Group extends GroupBase<Option>>({
children,
...props
}: ValueContainerProps<Option, IsMulti, Group>) => {
if (!props.hasValue) {
return <components.ValueContainer {...props}>{children as React.ReactNode[]}</components.ValueContainer>;
}
const CHIPS_LIMIT = 2;
// TODO:: fix the following ts error
// @ts-expect-error: @see children is an array but identified as object resulting in the error
const [chips, other] = children;
const overflowCounter = chips.slice(CHIPS_LIMIT).length;
const displayChips = chips.slice(overflowCounter, overflowCounter + CHIPS_LIMIT);
// console.log(props.getValue(), props.clearValue);
alishaz-polymath marked this conversation as resolved.
Show resolved Hide resolved
return (
<components.ValueContainer {...props}>
{displayChips}
{overflowCounter > 0 && (
<span className="flex items-center justify-center rounded-md bg-gray-100 py-[5px] px-2 text-[14px] font-medium leading-4 text-gray-700">
<>
<Icon.FiPlus className="mr-1 inline h-3 w-3 stroke-[3px]" /> <span>{overflowCounter} more</span>
</>
</span>
)}
{other}
</components.ValueContainer>
);
};

export const MultiDropdownSelect = ({ options = [], value = [], ...props }: Props) => {
// const { t } = useLocale();
const animationRef = useRef(null);

useEffect(() => {
animationRef.current && autoAnimate(animationRef.current);
}, [animationRef]);

return (
<Select
styles={{
multiValue: (styles) => {
return {
...styles,
backgroundColor: "#F3F4F6",
color: "#374151",
borderRadius: "6px",
padding: "5px 8px",
gap: "8px",
fontSize: "14px",
fontWeight: "500",
margin: "0px",
lineHeight: "16px",
};
},
multiValueLabel: (styles) => ({
...styles,
paddingLeft: "0px",
fontSize: "14px",
padding: "0",
}),
multiValueRemove: (base) => ({
...base,
color: "#4B5563",
padding: "0",
":hover": {
background: "transparent",
},
"> svg": {
width: "16px",
height: "17px",
},
}),
control: (base) => ({
...base,
// Brute force to remove focus outline of input
"& .cal-multiselect__input": {
borderWidth: 0,
boxShadow: "none",
caretColor: "transparent",
},
}),
valueContainer: (base) => ({
...base,
display: "flex",
gap: "4px",
paddingLeft: "5px",
padding: "0px",
height: "36px",
}),
}}
className="cal-multiselect"
classNamePrefix="cal-multiselect"
placeholder="Select"
defaultValue={value}
options={options}
hideSelectedOptions={false}
isMulti
components={{ ValueContainer: LimitedChipsContainer }}
{...props}
/>
);
};

export default MultiDropdownSelect;