mirror of
https://github.com/makeplane/plane
synced 2025-08-07 19:59:33 +00:00
[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:
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
|
||||
onOpen?: () => void;
|
||||
onClose?: () => void;
|
||||
containerClassName?: (isOpen: boolean) => string;
|
||||
containerClassName?: string | ((isOpen: boolean) => string);
|
||||
tabIndex?: number;
|
||||
placement?: Placement;
|
||||
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";
|
||||
// popper-js
|
||||
import sortBy from "lodash/sortBy";
|
||||
import React, { FC, useMemo, useRef, useState } from "react";
|
||||
import { usePopper } from "react-popper";
|
||||
// plane helpers
|
||||
// plane imports
|
||||
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 { DropdownOptions } from "./common/options";
|
||||
// hooks
|
||||
import { useDropdownKeyPressed } from "../hooks/use-dropdown-key-pressed";
|
||||
// helper
|
||||
import { cn } from "../../helpers";
|
||||
// types
|
||||
import { IMultiSelectDropdown } from "./dropdown";
|
||||
|
||||
export const MultiSelectDropdown: FC<IMultiSelectDropdown> = (props) => {
|
||||
@@ -118,7 +113,10 @@ export const MultiSelectDropdown: FC<IMultiSelectDropdown> = (props) => {
|
||||
ref={dropdownRef}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
className={cn("h-full", containerClassName)}
|
||||
className={cn(
|
||||
"h-full",
|
||||
typeof containerClassName === "function" ? containerClassName(isOpen) : containerClassName
|
||||
)}
|
||||
tabIndex={tabIndex}
|
||||
multiple
|
||||
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";
|
||||
// popper-js
|
||||
import sortBy from "lodash/sortBy";
|
||||
import React, { FC, useMemo, useRef, useState } from "react";
|
||||
import { usePopper } from "react-popper";
|
||||
// plane helpers
|
||||
// plane imports
|
||||
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 { DropdownOptions } from "./common/options";
|
||||
// hooks
|
||||
import { useDropdownKeyPressed } from "../hooks/use-dropdown-key-pressed";
|
||||
// helper
|
||||
import { cn } from "../../helpers";
|
||||
// types
|
||||
import { ISingleSelectDropdown } from "./dropdown";
|
||||
|
||||
export const Dropdown: FC<ISingleSelectDropdown> = (props) => {
|
||||
@@ -118,7 +113,10 @@ export const Dropdown: FC<ISingleSelectDropdown> = (props) => {
|
||||
ref={dropdownRef}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
className={cn("h-full", containerClassName)}
|
||||
className={cn(
|
||||
"h-full",
|
||||
typeof containerClassName === "function" ? containerClassName(isOpen) : containerClassName
|
||||
)}
|
||||
tabIndex={tabIndex}
|
||||
onKeyDown={handleKeyDown}
|
||||
disabled={disabled}
|
||||
|
||||
@@ -86,36 +86,6 @@ export const copyUrlToClipboard = async (path: string) => {
|
||||
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
|
||||
* @param {string} str - Input string
|
||||
@@ -275,6 +245,33 @@ export const checkURLValidity = (url: string): boolean => {
|
||||
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
|
||||
// let copyTextToClipboard: (text: string) => Promise<void>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user