[WEB-4154] fix: dropdown container classname (#7085)
* fix: dropdown container classname * improvement: update string utils for joinWithConjunction * improvement: add more string utils
This commit is contained in:
parent
0a8cc24da5
commit
4460529b37
4 changed files with 48 additions and 55 deletions
2
packages/ui/src/dropdown/dropdown.d.ts
vendored
2
packages/ui/src/dropdown/dropdown.d.ts
vendored
|
|
@ -4,7 +4,7 @@ export interface IDropdown {
|
||||||
// root props
|
// root props
|
||||||
onOpen?: () => void;
|
onOpen?: () => void;
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
containerClassName?: (isOpen: boolean) => string;
|
containerClassName?: string | ((isOpen: boolean) => string);
|
||||||
tabIndex?: number;
|
tabIndex?: number;
|
||||||
placement?: Placement;
|
placement?: Placement;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,14 @@
|
||||||
import React, { FC, useMemo, useRef, useState } from "react";
|
|
||||||
import sortBy from "lodash/sortBy";
|
|
||||||
// headless ui
|
|
||||||
import { Combobox } from "@headlessui/react";
|
import { Combobox } from "@headlessui/react";
|
||||||
// popper-js
|
import sortBy from "lodash/sortBy";
|
||||||
|
import React, { FC, useMemo, useRef, useState } from "react";
|
||||||
import { usePopper } from "react-popper";
|
import { usePopper } from "react-popper";
|
||||||
// plane helpers
|
// plane imports
|
||||||
import { useOutsideClickDetector } from "@plane/hooks";
|
import { useOutsideClickDetector } from "@plane/hooks";
|
||||||
// components
|
// local imports
|
||||||
|
import { cn } from "../../helpers";
|
||||||
|
import { useDropdownKeyPressed } from "../hooks/use-dropdown-key-pressed";
|
||||||
import { DropdownButton } from "./common";
|
import { DropdownButton } from "./common";
|
||||||
import { DropdownOptions } from "./common/options";
|
import { DropdownOptions } from "./common/options";
|
||||||
// hooks
|
|
||||||
import { useDropdownKeyPressed } from "../hooks/use-dropdown-key-pressed";
|
|
||||||
// helper
|
|
||||||
import { cn } from "../../helpers";
|
|
||||||
// types
|
|
||||||
import { IMultiSelectDropdown } from "./dropdown";
|
import { IMultiSelectDropdown } from "./dropdown";
|
||||||
|
|
||||||
export const MultiSelectDropdown: FC<IMultiSelectDropdown> = (props) => {
|
export const MultiSelectDropdown: FC<IMultiSelectDropdown> = (props) => {
|
||||||
|
|
@ -118,7 +113,10 @@ export const MultiSelectDropdown: FC<IMultiSelectDropdown> = (props) => {
|
||||||
ref={dropdownRef}
|
ref={dropdownRef}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
className={cn("h-full", containerClassName)}
|
className={cn(
|
||||||
|
"h-full",
|
||||||
|
typeof containerClassName === "function" ? containerClassName(isOpen) : containerClassName
|
||||||
|
)}
|
||||||
tabIndex={tabIndex}
|
tabIndex={tabIndex}
|
||||||
multiple
|
multiple
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,14 @@
|
||||||
import React, { FC, useMemo, useRef, useState } from "react";
|
|
||||||
import sortBy from "lodash/sortBy";
|
|
||||||
// headless ui
|
|
||||||
import { Combobox } from "@headlessui/react";
|
import { Combobox } from "@headlessui/react";
|
||||||
// popper-js
|
import sortBy from "lodash/sortBy";
|
||||||
|
import React, { FC, useMemo, useRef, useState } from "react";
|
||||||
import { usePopper } from "react-popper";
|
import { usePopper } from "react-popper";
|
||||||
// plane helpers
|
// plane imports
|
||||||
import { useOutsideClickDetector } from "@plane/hooks";
|
import { useOutsideClickDetector } from "@plane/hooks";
|
||||||
// components
|
// local imports
|
||||||
|
import { cn } from "../../helpers";
|
||||||
|
import { useDropdownKeyPressed } from "../hooks/use-dropdown-key-pressed";
|
||||||
import { DropdownButton } from "./common";
|
import { DropdownButton } from "./common";
|
||||||
import { DropdownOptions } from "./common/options";
|
import { DropdownOptions } from "./common/options";
|
||||||
// hooks
|
|
||||||
import { useDropdownKeyPressed } from "../hooks/use-dropdown-key-pressed";
|
|
||||||
// helper
|
|
||||||
import { cn } from "../../helpers";
|
|
||||||
// types
|
|
||||||
import { ISingleSelectDropdown } from "./dropdown";
|
import { ISingleSelectDropdown } from "./dropdown";
|
||||||
|
|
||||||
export const Dropdown: FC<ISingleSelectDropdown> = (props) => {
|
export const Dropdown: FC<ISingleSelectDropdown> = (props) => {
|
||||||
|
|
@ -118,7 +113,10 @@ export const Dropdown: FC<ISingleSelectDropdown> = (props) => {
|
||||||
ref={dropdownRef}
|
ref={dropdownRef}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
className={cn("h-full", containerClassName)}
|
className={cn(
|
||||||
|
"h-full",
|
||||||
|
typeof containerClassName === "function" ? containerClassName(isOpen) : containerClassName
|
||||||
|
)}
|
||||||
tabIndex={tabIndex}
|
tabIndex={tabIndex}
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
|
|
||||||
|
|
@ -86,36 +86,6 @@ export const copyUrlToClipboard = async (path: string) => {
|
||||||
await copyTextToClipboard(url.toString());
|
await copyTextToClipboard(url.toString());
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Generates a deterministic HSL color based on input string
|
|
||||||
* @param {string} string - Input string to generate color from
|
|
||||||
* @returns {string} HSL color string
|
|
||||||
* @example
|
|
||||||
* generateRandomColor("hello") // returns consistent HSL color for "hello"
|
|
||||||
* generateRandomColor("") // returns "rgb(var(--color-primary-100))"
|
|
||||||
*/
|
|
||||||
export const generateRandomColor = (string: string): string => {
|
|
||||||
if (!string) return "rgb(var(--color-primary-100))";
|
|
||||||
|
|
||||||
string = `${string}`;
|
|
||||||
|
|
||||||
const uniqueId = string.length.toString() + string;
|
|
||||||
const combinedString = uniqueId + string;
|
|
||||||
|
|
||||||
const hash = Array.from(combinedString).reduce((acc, char) => {
|
|
||||||
const charCode = char.charCodeAt(0);
|
|
||||||
return (acc << 5) - acc + charCode;
|
|
||||||
}, 0);
|
|
||||||
|
|
||||||
const hue = hash % 360;
|
|
||||||
const saturation = 70;
|
|
||||||
const lightness = 60;
|
|
||||||
|
|
||||||
const randomColor = `hsl(${hue}, ${saturation}%, ${lightness}%)`;
|
|
||||||
|
|
||||||
return randomColor;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Gets first character of first word or first characters of first two words
|
* @description Gets first character of first word or first characters of first two words
|
||||||
* @param {string} str - Input string
|
* @param {string} str - Input string
|
||||||
|
|
@ -275,6 +245,33 @@ export const checkURLValidity = (url: string): boolean => {
|
||||||
return urlPattern.test(url);
|
return urlPattern.test(url);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combines array elements with a separator and adds a conjunction before the last element
|
||||||
|
* @param array Array of strings to combine
|
||||||
|
* @param separator Separator to use between elements (default: ", ")
|
||||||
|
* @param conjunction Conjunction to use before last element (default: "and")
|
||||||
|
* @returns Combined string with conjunction before the last element
|
||||||
|
*/
|
||||||
|
export const joinWithConjunction = (array: string[], separator: string = ", ", conjunction: string = "and"): string => {
|
||||||
|
if (!array || array.length === 0) return "";
|
||||||
|
if (array.length === 1) return array[0];
|
||||||
|
if (array.length === 2) return `${array[0]} ${conjunction} ${array[1]}`;
|
||||||
|
|
||||||
|
const lastElement = array[array.length - 1];
|
||||||
|
const elementsExceptLast = array.slice(0, -1);
|
||||||
|
|
||||||
|
return `${elementsExceptLast.join(separator)}${separator}${conjunction} ${lastElement}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Ensures a URL has a protocol
|
||||||
|
* @param {string} url
|
||||||
|
* @returns {string}
|
||||||
|
* @example
|
||||||
|
* ensureUrlHasProtocol("example.com") => "http://example.com"
|
||||||
|
*/
|
||||||
|
export const ensureUrlHasProtocol = (url: string): string => (url.startsWith("http") ? url : `http://${url}`);
|
||||||
|
|
||||||
// Browser-only clipboard functions
|
// Browser-only clipboard functions
|
||||||
// let copyTextToClipboard: (text: string) => Promise<void>;
|
// let copyTextToClipboard: (text: string) => Promise<void>;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue