cal.pub0.org/packages/ui/v2/form/Select.tsx

113 lines
3.1 KiB
TypeScript
Raw Normal View History

Feat/design system (#3051) * Storybook Boilerplate setup * Inital Setup * First story * Color Design System * Badge Story + Comp * Checkbox UI + Stories * Update Red colors + Button Group * Switch+Stories / Default brand color * Update Version + Button Group combined * Compact Butotn Group * Tidy up Selectors * Adds Tooltip to Button * TextInput * Update SB * Prefix Input * Match text area styles * Prefix Controls * Update spacing on text area * Text Input Suffix * Color Picker * Update storybook * Icon Suffix/Prefix * Datepicker + move components to monorepo * Text color on labels * Move Radio over to monorepo * Move CustomBranding to calcom/ib * Radio * IconBadge Component * Update radio indicator background * Disabled radio state * Delete yarn.lock * Revert "Delete yarn.lock" This reverts commit 9b99d244b70872153a16bec1f1f3bc651e94be7a. * Fix webhook test * Replace old toast location * Update radio path * Empty State * Update Badge.tsx * Update Badge.tsx * Banner Component+story * Creation Modal * Creation Dialog updated * Button hover dialog * Confirmation Modal * Datepicker (Booking) * PageHeader * Fix border width * PageHeader update search bar * Fix input height * Fix button group size * Add spacing between badges - font smoothing * Update button position on banner * Banner update * Fixing focus state on suffix/prefix inputs * Implement A11y addon * Add aria label * error && "text-red-800" * Fix button hover * Change colors * Generate snapshot tests for on hover button * Revert colors to demo * Change colors * Fix Linear Issues * Form Stepper component * Add padding back to input * Move ui to UI_V2 * Use V2 * Update imports for v1 * Update imports for v1 * Upgrade to nextjs in storybook root * Update website submodule * Avatar Groups * Fix webpack again * Vertical Tab Item [WIP] - active state on small item is not working currently * Vertical Tab Group * Add Github action * Fix website submodule * Fix GH action * Rename Workflow * Adds lint report for CI * Lint report fixes * NavigationItem comments * VerticalTabItem type fixes * Fix avatar blur * Fix comments * Adding isEmbed to window object * Disable components that use router mock. * Load inter via google fonts * Started select * Adding base Breadcrumb * Update readme * Formatting * Fixes * Dependencies matching * Linting * Update FormStep.stories.tsx * Linting * Update MultiSelectCheckboxes.tsx Co-authored-by: zomars <zomars@me.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2022-07-23 00:39:50 +00:00
import { useSelect } from "downshift";
import { useState } from "react";
import { classNames } from "@calcom/lib";
type IItem =
| {
itemType: "ListItem";
title: string;
description: string;
value: string;
}
| {
itemType: "Title";
title: string;
value: string;
}
| {
itemType: "NameCard";
img: string;
value: string;
name: string;
}
| {
itemType: "Spacer";
};
interface SelectProps {
items: IItem[];
}
function itemToString(item: IItem | null) {
return item && item.itemType !== "Spacer" && item?.value ? item.value : "";
}
function Select({ items }: SelectProps) {
const [selectedItems, setSelectedItems] = useState<IItem[]>([]);
const {
isOpen,
selectedItem,
getToggleButtonProps,
getLabelProps,
getMenuProps,
highlightedIndex,
getItemProps,
} = useSelect<IItem>({
items,
itemToString,
selectedItem: null,
onSelectedItemChange: ({ selectedItem }) => {
if (!selectedItem) {
return;
}
const index = selectedItems.indexOf(selectedItem);
if (index > 0) {
setSelectedItems([...selectedItems.slice(0, index), ...selectedItems.slice(index + 1)]);
} else if (index === 0) {
setSelectedItems([...selectedItems.slice(1)]);
} else {
setSelectedItems([...selectedItems, selectedItem]);
}
},
});
const buttonText = selectedItems.length ? `${selectedItems.length} elements selected` : "Elements";
return (
<div>
<div className="flex w-72 flex-col gap-1">
<label {...getLabelProps()}>Choose your favorite book:</label>
<button
aria-label="toggle menu"
className="flex justify-between bg-white p-2"
type="button"
{...getToggleButtonProps()}>
<span>{buttonText}</span>
<span className="px-2">{isOpen ? <>&#8593;</> : <>&#8595;</>}</span>
</button>
</div>
<ul {...getMenuProps()} className="absolute max-h-80 w-72 overflow-scroll bg-white shadow-md">
{isOpen &&
items.map((item, index) => {
if (item.itemType === "Spacer") return; // Return a spacer that isnt selectable
return (
<li
className={classNames(
// highlightedIndex == index && 'bg-blue-300',
// selectedItem === item && 'font-bold',
"flex items-center gap-3 py-2 px-3 shadow-sm"
)}
key={`${item.value}${index}`}
{...getItemProps({ item, index })}>
<input
type="checkbox"
className="h-5 w-5"
checked={selectedItems.includes(item)}
value={item.value}
onChange={() => null}
/>
<div className="flex flex-col">
<span>{item.value}</span>
{/* {<span className="text-sm text-gray-700">{item.description}</span>} */}
</div>
</li>
);
})}
</ul>
</div>
);
}
export default Select;