diff options
Diffstat (limited to 'packages/components/src')
17 files changed, 919 insertions, 929 deletions
diff --git a/packages/components/src/components/Button/Button.scss b/packages/components/src/components/Button/Button.scss index bbe2e2470..b2fb48344 100644 --- a/packages/components/src/components/Button/Button.scss +++ b/packages/components/src/components/Button/Button.scss @@ -53,7 +53,7 @@ &.inactive { &:hover { .background { - filter: opacity(0) !important; + filter: opacity(0); } } } @@ -63,13 +63,13 @@ filter: opacity(0); &.active { - filter: opacity(0.2) !important; + filter: opacity(0.5); } } &:hover { .background { - filter: opacity(0.2); + filter: opacity(0.3); } } } @@ -79,7 +79,7 @@ filter: opacity(0); &.active { - filter: opacity(0.2) !important; + filter: opacity(0.2); } } @@ -96,12 +96,12 @@ } .background { - filter: opacity(1) !important; + filter: opacity(1); } &:hover { .background { - filter: brightness(0.8); + filter: opacity(0.3); } } } diff --git a/packages/components/src/components/Button/Button.tsx b/packages/components/src/components/Button/Button.tsx index a91c74a4c..885403640 100644 --- a/packages/components/src/components/Button/Button.tsx +++ b/packages/components/src/components/Button/Button.tsx @@ -1,195 +1,188 @@ -import { Tooltip } from '@mui/material' -import React from 'react' -import { Alignment, IGlobalProps, Placement, Type , getFormLabelSize } from '../../global' -import { Colors, Size } from '../../global/globalEnums' -import { getFontSize, getHeight, isDark } from '../../global/globalUtils' -import { IconButton } from '../IconButton' -import './Button.scss' +import { Tooltip } from '@mui/material'; +import React from 'react'; +import { Alignment, IGlobalProps, Placement, Type, getFormLabelSize } from '../../global'; +import { Colors, Size } from '../../global/globalEnums'; +import { getFontSize, getHeight } from '../../global/globalUtils'; +import { IconButton } from '../IconButton'; +import './Button.scss'; export interface IButtonProps extends IGlobalProps { - onClick?: (event: React.MouseEvent) => void - onDoubleClick?: (event: React.MouseEvent) => void - type?: Type - active?: boolean + onClick?: (event: React.MouseEvent) => void; + onDoubleClick?: (event: React.MouseEvent) => void; + type?: Type; + active?: boolean; - // Content - text?: string - icon?: JSX.Element | string + // Content + text?: string; + icon?: JSX.Element | string; - // Additional stylization - iconPlacement?: Placement - color?: string - colorPicker?: string, - uppercase?: boolean, - align?: Alignment + // Additional stylization + iconPlacement?: Placement; + color?: string; + colorPicker?: string; + uppercase?: boolean; + align?: Alignment; + filter?: string; } export const Button = (props: IButtonProps) => { - const { - text, - icon, - onClick, - onDoubleClick, - onPointerDown, - active, - height, - inactive, - type = Type.PRIM, - label, - uppercase = false, - iconPlacement = 'right', - size = Size.SMALL, - color = Colors.MEDIUM_BLUE, - background, - style, - tooltip, - tooltipPlacement = 'top', - colorPicker, - formLabel, - formLabelPlacement, - fillWidth, - align = fillWidth ? 'flex-start' : 'center' - } = props + const { + text, + icon, + onClick, + onDoubleClick, + onPointerDown, + active, + height, + inactive, + type = Type.PRIM, + filter, + uppercase = false, + iconPlacement = 'right', + size = Size.SMALL, + color = Colors.MEDIUM_BLUE, + background, + style, + tooltip, + tooltipPlacement = 'top', + colorPicker, + formLabel, + formLabelPlacement, + fillWidth, + align = fillWidth ? 'flex-start' : 'center', + } = props; - if (!text) { - return <IconButton {...props}/> - } - - /** - * Pointer down - * @param e - */ - const handlePointerDown = (e: React.PointerEvent) => { - - if (!inactive && onPointerDown) { - e.stopPropagation(); - e.preventDefault(); - onPointerDown(e) + if (!text) { + return <IconButton {...props} />; } - } - /** - * In the event that there is a single click - * @param e - */ - const handleClick = (e: React.MouseEvent) => { - if (!inactive && onClick) { - e.stopPropagation(); - e.preventDefault(); - onClick(e) - } - } + /** + * Pointer down + * @param e + */ + const handlePointerDown = (e: React.PointerEvent) => { + if (!inactive && onPointerDown) { + e.stopPropagation(); + e.preventDefault(); + onPointerDown(e); + } + }; - /** - * Double click - * @param e - */ - const handleDoubleClick = (e: React.MouseEvent) => { - if (!inactive && onDoubleClick){ - e.stopPropagation(); - e.preventDefault(); - onDoubleClick(e) - } - } + /** + * In the event that there is a single click + * @param e + */ + const handleClick = (e: React.MouseEvent) => { + if (!inactive && onClick) { + e.stopPropagation(); + e.preventDefault(); + onClick(e); + } + }; - const getBorderColor = (): Colors | string | undefined => { - switch(type){ - case Type.PRIM: - return undefined; - case Type.SEC: - if (colorPicker) return colorPicker; - return color; - case Type.TERT: - if (colorPicker) return colorPicker; - if (active) return color; - else return color; - } - } + /** + * Double click + * @param e + */ + const handleDoubleClick = (e: React.MouseEvent) => { + if (!inactive && onDoubleClick) { + e.stopPropagation(); + e.preventDefault(); + onDoubleClick(e); + } + }; - const getColor = (): Colors | string | undefined => { - if (color && background) return color; - switch(type){ - case Type.PRIM: - if (colorPicker) return colorPicker - return color; - case Type.SEC: - if (colorPicker) return colorPicker - return color; - case Type.TERT: - if (colorPicker) { - if (isDark(colorPicker)) return Colors.WHITE; - else return Colors.BLACK + const getBorderColor = (): Colors | string | undefined => { + switch (type) { + case Type.PRIM: + return undefined; + case Type.SEC: + if (colorPicker) return colorPicker; + return color; + case Type.TERT: + return color; } - if (isDark(color)) return Colors.WHITE; - else return Colors.BLACK - } - } + }; - const getBackground = (): Colors | string | undefined => { - if (background) return background; - switch(type) { - case Type.PRIM: - if (colorPicker) return colorPicker - return color; - case Type.SEC: - if (colorPicker) return colorPicker - return color; - case Type.TERT: - if (colorPicker) return colorPicker - else return color - } - } + const getColor = (): Colors | string | undefined => { + if (color && background) return color; + switch (type) { + case Type.PRIM: + case Type.SEC: + if (colorPicker) return colorPicker; + return color; + case Type.TERT: + return ''; + } + }; - const defaultProperties: React.CSSProperties = { - height: getHeight(height, size), - minHeight: getHeight(height, size), - width: fillWidth ? '100%' : 'fit-content', - justifyContent: align ? align : undefined, - padding: fillWidth && align === 'center' ? 0 : undefined, - fontWeight: 500, - fontSize: getFontSize(size), - fontFamily: 'sans-serif', - textTransform: uppercase ? 'uppercase' : undefined, - borderColor: getBorderColor(), - color: getColor(), - } + const getBackground = (): Colors | string | undefined => { + if (background) return background; + switch (type) { + case Type.PRIM: + case Type.SEC: + if (colorPicker) return colorPicker; + return color; + case Type.TERT: + } + }; - const backgroundProperties: React.CSSProperties = { - background: getBackground() - } + const defaultProperties: React.CSSProperties = { + height: getHeight(height, size), + minHeight: getHeight(height, size), + width: fillWidth ? '100%' : 'fit-content', + justifyContent: align ? align : undefined, + padding: fillWidth && align === 'center' ? 0 : undefined, + fontWeight: 500, + fontSize: getFontSize(size), + fontFamily: 'sans-serif', + textTransform: uppercase ? 'uppercase' : undefined, + borderColor: getBorderColor(), + color: getColor(), + }; - const button: JSX.Element = ( - <Tooltip disableInteractive={true} arrow={true} placement={tooltipPlacement} title={tooltip}> - <div - className={`button-container ${type} ${active && 'active'} ${inactive && 'inactive'}`} - onClick={handleClick} - onDoubleClick={handleDoubleClick} - onPointerDown={handlePointerDown} - style={{...defaultProperties, ...style}} - > - <div className={`button-content`} - style={{justifyContent: align}} - > - {iconPlacement == 'left' && icon ? <div className={`icon`} style={{ - fontSize: getFontSize(size, true) - }}>{icon}</div> : null} - {text} - {iconPlacement == 'right' && icon ? <div className={`icon`} style={{ - fontSize: getFontSize(size, true) - }}>{icon}</div> : null} - </div> - <div className={`background ${active && 'active'}`} style={backgroundProperties}/> - </div> - </Tooltip> - ) + const backgroundProperties: React.CSSProperties = { + background: getBackground(), + filter, + }; - return ( - formLabel ? - <div className={`form-wrapper ${formLabelPlacement}`} style={{ width: fillWidth ? '100%' : undefined}}> - <div className={'formLabel'} style={{fontSize: getFormLabelSize(size)}}>{formLabel}</div> - {button} - </div> - : - button - ) -} + const button: JSX.Element = ( + <Tooltip disableInteractive={true} arrow={true} placement={tooltipPlacement} title={tooltip}> + <div className={`button-container ${type} ${active && 'active'} ${inactive && 'inactive'}`} onClick={handleClick} onDoubleClick={handleDoubleClick} onPointerDown={handlePointerDown} style={{ ...defaultProperties, ...style }}> + <div className="button-content" style={{ justifyContent: align }}> + {iconPlacement == 'left' && icon ? ( + <div + className="icon" + style={{ + fontSize: getFontSize(size, true), + }}> + {icon} + </div> + ) : null} + {text} + {iconPlacement == 'right' && icon ? ( + <div + className="icon" + style={{ + fontSize: getFontSize(size, true), + }}> + {icon} + </div> + ) : null} + </div> + <div className={`background ${active && 'active'}`} style={backgroundProperties} /> + </div> + </Tooltip> + ); + + return formLabel ? ( + <div className={`form-wrapper ${formLabelPlacement}`} style={{ width: fillWidth ? '100%' : undefined }}> + <div className="formLabel" style={{ fontSize: getFormLabelSize(size) }}> + {formLabel} + </div> + {button} + </div> + ) : ( + button + ); +}; diff --git a/packages/components/src/components/ColorPicker/ColorPicker.tsx b/packages/components/src/components/ColorPicker/ColorPicker.tsx index 632b470f0..72e02d955 100644 --- a/packages/components/src/components/ColorPicker/ColorPicker.tsx +++ b/packages/components/src/components/ColorPicker/ColorPicker.tsx @@ -1,5 +1,5 @@ import React, { useRef, useState } from 'react'; -import { GithubPicker, ChromePicker, BlockPicker, SliderPicker, SketchPicker } from 'react-color'; +import { GithubPicker, ChromePicker, BlockPicker, SliderPicker, SketchPicker, ColorResult } from 'react-color'; import { IGlobalProps, Size, Type, getFormLabelSize } from '../../global'; import { Button } from '../Button'; import { IconButton } from '../IconButton'; @@ -16,12 +16,12 @@ export interface IColorPickerProps extends IGlobalProps { colorPickerType?: ColorPickerType; defaultPickerType?: ColorPickerType; selectedColor?: string; - setSelectedColor: (color: any) => unknown; - setFinalColor: (color: any) => unknown; + setSelectedColor: (color: string) => unknown; + setFinalColor: (color: string) => unknown; } export const ColorPicker = (props: IColorPickerProps) => { - const [selectedColorLoc, setSelectedColorLoc] = useState(); + const [selectedColorLoc, setSelectedColorLoc] = useState<string>(); const { defaultPickerType, text, @@ -31,6 +31,7 @@ export const ColorPicker = (props: IColorPickerProps) => { size = Size.SMALL, type = Type.TERT, icon, + background, selectedColor = selectedColorLoc, setSelectedColor = setSelectedColorLoc, setFinalColor = setSelectedColorLoc, @@ -40,32 +41,25 @@ export const ColorPicker = (props: IColorPickerProps) => { } = props; const [isOpen, setOpen] = useState<boolean>(false); const [pickerSelectorOpen, setPickerSelectorOpen] = useState<boolean>(false); - const decimalToHexString = (number: number) => { + const decimalToHexString = (numberIn: number) => { + let number = numberIn; if (number < 0) { number = 0xffffffff + number + 1; } return (number < 16 ? '0' : '') + number.toString(16).toUpperCase(); }; - const colorString = (color: any) => { - return color.hex === 'transparent' ? color.hex : color.hex + (color.rgb.a ? decimalToHexString(Math.round(color.rgb.a * 255)) : 'ff'); - }; - const onChange = (color: any) => { - setSelectedColor(colorString(color) as any); - }; - const onChangeComplete = (color: any) => { - setFinalColor(colorString(color) as any); - }; + const colorString = (c: ColorResult) => (c.hex === 'transparent' ? c.hex : c.hex + (c.rgb.a ? decimalToHexString(Math.round(c.rgb.a * 255)) : 'ff')); + const onChange = (c: ColorResult) => setSelectedColor(colorString(c)); + const onChangeComplete = (c: ColorResult) => setFinalColor(colorString(c)); const [picker, setPicker] = useState<string>(defaultPickerType ?? 'Classic'); const toggleRef = useRef<HTMLDivElement | null>(null); const getToggle = () => ( <div ref={toggleRef}> - {icon && !text ? ( - <IconButton active={isOpen} tooltip={tooltip} type={type} color={color} size={size} icon={icon} colorPicker={selectedColor} fillWidth={fillWidth} /> - ) : text ? ( - <Button active={isOpen} tooltip={tooltip} size={size} type={type} color={color} text={text} icon={icon} align={'flex-start'} iconPlacement={'left'} colorPicker={selectedColor} fillWidth={fillWidth} /> + {text && !icon ? ( + <Button active={isOpen} tooltip={tooltip} size={size} type={type} background={background} color={color} text={text} icon={icon} align="flex-start" iconPlacement="left" colorPicker={selectedColor} fillWidth={fillWidth} /> ) : ( - <IconButton active={isOpen} tooltip={tooltip} type={type} color={color} size={size} icon={icon} colorPicker={selectedColor} fillWidth={fillWidth} /> + <IconButton active={isOpen} tooltip={tooltip} type={type} color={color} background={background} size={size} icon={icon} colorPicker={selectedColor} fillWidth={fillWidth} /> )} </div> ); @@ -92,14 +86,12 @@ export const ColorPicker = (props: IColorPickerProps) => { ); } // prettier-ignore }; - const openChanged = (isOpen: boolean) => setPickerSelectorOpen(isOpen); + const openChanged = (state: boolean) => setPickerSelectorOpen(state); const getPopup = (): JSX.Element => { if (colorPickerType) { return getColorPicker(colorPickerType); } else { - // Todo: this would be much easier if the selectedColor was a Color, not a string. - const newColor = selectedColor === 'transparent' ? 'white' : selectedColor?.startsWith('#') ? selectedColor.substring(0, 7) : selectedColor?.startsWith('rgba') ? selectedColor?.replace(/,[0-9]*\)/, '1)') : selectedColor; return ( <div style={{ height: 'fit-content' }}> <Dropdown @@ -109,9 +101,10 @@ export const ColorPicker = (props: IColorPickerProps) => { val: item, }; })} + background={background} activeChanged={openChanged} placement={'right'} - color={newColor} + color={color} type={Type.PRIM} dropdownType={DropdownType.SELECT} selectedVal={picker} @@ -126,7 +119,7 @@ export const ColorPicker = (props: IColorPickerProps) => { const popupContainsPt = (x: number, y: number) => { const rect = toggleRef.current?.getBoundingClientRect(); - return rect && rect.left < x && rect.top < y && rect.right > x && rect.bottom > y; + return pickerSelectorOpen || (rect && rect.left < x && rect.top < y && rect.right > x && rect.bottom > y) ? true : false; }; const colorPicker: JSX.Element = ( @@ -138,6 +131,7 @@ export const ColorPicker = (props: IColorPickerProps) => { tooltip={tooltip} size={size} color={selectedColor} + background={background} popup={getPopup()} popupContainsPt={popupContainsPt} // this should prohbably test to see if the click pt is actually within the picker selector list popup. /> @@ -145,7 +139,7 @@ export const ColorPicker = (props: IColorPickerProps) => { return formLabel ? ( <div className={`form-wrapper ${formLabelPlacement}`} style={{ width: fillWidth ? '100%' : undefined }}> - <div className={'formLabel'} style={{ fontSize: getFormLabelSize(size) }}> + <div className="formLabel" style={{ fontSize: getFormLabelSize(size) }}> {formLabel} </div> {colorPicker} diff --git a/packages/components/src/components/Dropdown/Dropdown.tsx b/packages/components/src/components/Dropdown/Dropdown.tsx index b9b6f01b8..783c7daa4 100644 --- a/packages/components/src/components/Dropdown/Dropdown.tsx +++ b/packages/components/src/components/Dropdown/Dropdown.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import { FaCaretDown, FaCaretLeft, FaCaretRight, FaCaretUp } from 'react-icons/fa'; import { Popup, PopupTrigger } from '..'; -import { Colors, IGlobalProps, Placement, Type, getFontSize, getHeight, isDark, getFormLabelSize } from '../../global'; +import { Colors, IGlobalProps, Placement, Type, getFontSize, getHeight, getFormLabelSize } from '../../global'; import { IconButton } from '../IconButton'; import { ListBox } from '../ListBox'; import { IListItemProps, ListItem } from '../ListItem'; @@ -92,7 +92,7 @@ export const Dropdown = (props: IDropdownProps) => { textTransform: uppercase ? 'uppercase' : undefined, borderColor: getBorderColor(), background, - color: color && background ? color : type == Type.TERT ? (isDark(color) ? Colors.WHITE : Colors.BLACK) : color, + color: color, }; const backgroundProperties: React.CSSProperties = { @@ -116,9 +116,9 @@ export const Dropdown = (props: IDropdownProps) => { <div className={`dropdown-toggle${!selectedVal ? '-mini' : ''} ${type} ${inactive && 'inactive'}`} style={{ ...defaultProperties, height: getHeight(height, size), width: width }}> {selectedVal && <ListItem size={size} {...itemsMap.get(selectedVal)} style={{ color: defaultProperties.color, background: defaultProperties.background }} inactive />} <div className="toggle-caret"> - <IconButton size={size} icon={getCaretDirection(active, placement)} color={defaultProperties.color} inactive /> + <IconButton size={size} background={background} icon={getCaretDirection(active, placement)} color={defaultProperties.color} inactive /> </div> - <div className={`background ${active && 'active'}`} style={{ ...backgroundProperties }} /> + <div className={`background ${active && 'active'}`} style={{ ...backgroundProperties, filter: selectedVal ? 'opacity(0.3)' : 'opacity(0)' }} /> </div> ); case DropdownType.CLICK: @@ -127,9 +127,9 @@ export const Dropdown = (props: IDropdownProps) => { <div className={`dropdown-toggle${!selectedVal ? '-mini' : ''} ${type} ${inactive && 'inactive'}`} style={{ ...defaultProperties, height: getHeight(height, size), width: width }}> <ListItem val="title" text={title} size={size} style={{ color: defaultProperties.color, background: defaultProperties.backdropFilter }} inactive /> <div className="toggle-caret"> - <IconButton size={size} icon={getCaretDirection(active, placement)} color={defaultProperties.color} inactive /> + <IconButton size={size} background={background} icon={getCaretDirection(active, placement)} color={defaultProperties.color} inactive /> </div> - <div className={`background ${active && 'active'}`} style={{ ...backgroundProperties }} /> + <div className={`background ${active && 'active'}`} style={{ ...backgroundProperties, filter: selectedVal ? 'opacity(0.3)' : 'opacity(0)' }} /> </div> ); } @@ -157,6 +157,7 @@ export const Dropdown = (props: IDropdownProps) => { size={size} fillWidth={true} color={color} + background={background} popup={ <ListBox maxItems={maxItems} diff --git a/packages/components/src/components/DropdownSearch/DropdownSearch.tsx b/packages/components/src/components/DropdownSearch/DropdownSearch.tsx index 5ec01b44e..bdf114140 100644 --- a/packages/components/src/components/DropdownSearch/DropdownSearch.tsx +++ b/packages/components/src/components/DropdownSearch/DropdownSearch.tsx @@ -1,24 +1,24 @@ -import React, { useState } from 'react' -import * as fa from 'react-icons/fa' -import { EditableText, Popup, PopupTrigger } from '..' -import { IGlobalProps, Placement, Size, getHeight , getFormLabelSize } from '../../global' -import { IconButton } from '../IconButton' -import { ListBox } from '../ListBox' -import { IListItemProps } from '../ListItem' -import './DropdownSearch.scss' +import React, { useState } from 'react'; +import * as fa from 'react-icons/fa'; +import { EditableText, Popup, PopupTrigger } from '..'; +import { IGlobalProps, Placement, Size, getHeight } from '../../global'; +import { IconButton } from '../IconButton'; +import { ListBox } from '../ListBox'; +import { IListItemProps } from '../ListItem'; +import './DropdownSearch.scss'; export enum DropdownSearchType { - SELECT = "select", - CLICK = "click" + SELECT = 'select', + CLICK = 'click', } export interface IDropdownSearchProps extends IGlobalProps { - items: IListItemProps[] - placement: Placement - dropdownSearchType: DropdownSearchType - title?: string - selectedVal?: string | number - maxItems?: number + items: IListItemProps[]; + placement: Placement; + dropdownSearchType: DropdownSearchType; + title?: string; + selectedVal?: string | number; + maxItems?: number; } /** @@ -30,100 +30,76 @@ export interface IDropdownSearchProps extends IGlobalProps { * Look at: import Select from "react-select"; */ export const DropdownSearch = (props: IDropdownSearchProps) => { - const { - size, - height, - maxItems, - items, - dropdownSearchType, - selectedVal, - // setSelectedVal, - tooltip, - title = "DropdownSearch", - type, - width, - color - } = props + const { size, height, maxItems, items, dropdownSearchType, type, width, color } = props; - // const [selectedItem, setSelectedItem] = useState< - // IListItemProps | undefined - // >(selectedVal) + // const [selectedItem, setSelectedItem] = useState< + // IListItemProps | undefined + // >(selectedVal) - const [searchTerm, setSearchTerm] = useState<string | undefined>(undefined) - const [isEditing, setIsEditing] = useState<boolean>(false) - const [active, setActive] = useState<boolean>(false) + const [searchTerm, setSearchTerm] = useState<string | undefined>(undefined); + const [isEditing, setIsEditing] = useState<boolean>(false); + const [active, setActive] = useState<boolean>(false); - const getToggle = () => { - switch (dropdownSearchType) { - case DropdownSearchType.SELECT: - return (<div - className={`dropdownsearch-toggle ${type}`} - style={{ height: getHeight(height, size), width: width }} - onClick={(e) => { - e.stopPropagation() - !isEditing && setIsEditing(true) - }} - > - {/* {selectedItem && !isEditing ? ( + const getToggle = () => { + switch (dropdownSearchType) { + case DropdownSearchType.SELECT: + return ( + <div + className={`dropdownsearch-toggle ${type}`} + style={{ height: getHeight(height, size), width: width }} + onClick={e => { + e.stopPropagation(); + !isEditing && setIsEditing(true); + }}> + {/* {selectedItem && !isEditing ? ( <ListItem {...selectedItem} inactive /> ) : ( */} - <div className="toggle-button"> - <EditableText - type={type} - val={searchTerm} - placeholder={'...'} - editing={true} - // onEdit={(val) => { - // setSearchTerm(val) - // }} - size={Size.SMALL} - setEditing={setIsEditing} - /> - </div> - {/* )} */} - <div className="toggle-caret"> - <IconButton - size={Size.SMALL} - icon={<fa.FaSearch />} - inactive - /> - </div> - <div className={`toggle-background ${isEditing && 'active'}`}/> - </div>); - case DropdownSearchType.CLICK: - default: - return ( - <div - className={`dropdownsearch-toggle ${type}`} - style={{ height: getHeight(height, size), width: width }} - > - </div> - ) - } - } + <div className="toggle-button"> + <EditableText + type={type} + val={searchTerm} + placeholder={'...'} + editing={true} + // onEdit={(val) => { + // setSearchTerm(val) + // }} + size={Size.SMALL} + setEditing={setIsEditing} + /> + </div> + {/* )} */} + <div className="toggle-caret"> + <IconButton size={Size.SMALL} icon={<fa.FaSearch />} inactive /> + </div> + <div className={`toggle-background ${isEditing && 'active'}`} /> + </div> + ); + case DropdownSearchType.CLICK: + default: + return <div className={`dropdownsearch-toggle ${type}`} style={{ height: getHeight(height, size), width: width }}></div>; + } + }; - return ( - <div - className="dropdownsearch-container" - > - <Popup - toggle={getToggle()} - trigger={PopupTrigger.CLICK} - isOpen={active} - setOpen={setActive} - size={size} - color={color} - popup={ - <ListBox - maxItems={maxItems} - items={items} - filter={searchTerm} - // selectedVal={selectedVal} - // setSelectedVal={setSelectedItem} - size={size} - /> - } - /> - </div> - ) -} + return ( + <div className="dropdownsearch-container"> + <Popup + toggle={getToggle()} + trigger={PopupTrigger.CLICK} + isOpen={active} + setOpen={setActive} + size={size} + color={color} + popup={ + <ListBox + maxItems={maxItems} + items={items} + filter={searchTerm} + // selectedVal={selectedVal} + // setSelectedVal={setSelectedItem} + size={size} + /> + } + /> + </div> + ); +}; diff --git a/packages/components/src/components/EditableText/EditableText.tsx b/packages/components/src/components/EditableText/EditableText.tsx index c361cf183..56cbc064d 100644 --- a/packages/components/src/components/EditableText/EditableText.tsx +++ b/packages/components/src/components/EditableText/EditableText.tsx @@ -1,21 +1,21 @@ -import React, { useState } from 'react' -import { Colors, IGlobalProps, Size, TextAlignment, Type, getFontSize, getFormLabelSize, getHeight, isDark } from '../../global' -import './EditableText.scss' -import { Toggle, ToggleType } from '../Toggle' -import { FaEye, FaEyeSlash} from 'react-icons/fa' +import React, { useState } from 'react'; +import { Colors, IGlobalProps, Size, TextAlignment, Type, getFontSize, getFormLabelSize, getHeight, isDark } from '../../global'; +import './EditableText.scss'; +import { Toggle, ToggleType } from '../Toggle'; +import { FaEye, FaEyeSlash } from 'react-icons/fa'; export interface IEditableTextProps extends IGlobalProps { - val?: string | number - setVal?: (newText: string | number) => unknown - onEnter?: (newText: string | number) => unknown - setEditing?: (bool: boolean) => unknown - placeholder?: string - editing?: boolean - size?: Size - height?: number - multiline?: boolean - textAlign?: TextAlignment - password?: boolean + val?: string | number; + setVal?: (newText: string | number) => unknown; + onEnter?: (newText: string | number) => unknown; + setEditing?: (bool: boolean) => unknown; + placeholder?: string; + editing?: boolean; + size?: Size; + height?: number; + multiline?: boolean; + textAlign?: TextAlignment; + password?: boolean; } /** @@ -25,152 +25,149 @@ export interface IEditableTextProps extends IGlobalProps { * @returns */ export const EditableText = (props: IEditableTextProps) => { - const [valLoc, setValLoc] = useState<string>('') - const [editingLoc, setEditingLoc] = useState<boolean>(false) - const { - height, - size, - val = valLoc, - setVal = setValLoc, - onEnter, - setEditing = setEditingLoc, - color = Colors.MEDIUM_BLUE, - background, - type = Type.PRIM, - placeholder, - width, - multiline, - textAlign = 'left', - formLabel, - formLabelPlacement, - fillWidth, - password, - editing = password ? true : editingLoc, - style - } = props - const [showPassword, setShowPassword] = useState<boolean>(false) + const [valLoc, setValLoc] = useState<string>(''); + const [editingLoc, setEditingLoc] = useState<boolean>(false); + const { + height, + size, + val = valLoc, + setVal = setValLoc, + onEnter, + setEditing = setEditingLoc, + color = Colors.MEDIUM_BLUE, + background, + type = Type.PRIM, + placeholder, + width, + textAlign = 'left', + formLabel, + formLabelPlacement, + fillWidth, + password, + editing = password ? true : editingLoc, + style, + } = props; + const [showPassword, setShowPassword] = useState<boolean>(false); - const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>) => { - setVal(event.target.value) - } - const handleKeyPress = (event: React.KeyboardEvent) => { - if (event.key === 'Enter') { - onEnter?.((event.target as HTMLInputElement).value) - } - } + const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>) => { + setVal(event.target.value); + }; + const handleKeyPress = (event: React.KeyboardEvent) => { + if (event.key === 'Enter') { + onEnter?.((event.target as HTMLInputElement).value); + } + }; - const getBorderColor = (): Colors | string | undefined => { - switch(type){ - case Type.PRIM: - return undefined; - case Type.SEC: - return color; - case Type.TERT: - if (editing) return color; - else return color; - } - } + const getBorderColor = (): Colors | string | undefined => { + switch (type) { + case Type.PRIM: + return undefined; + case Type.SEC: + return color; + case Type.TERT: + if (editing) return color; + else return color; + } + }; - const getColor = (): Colors | string | undefined => { - if (color && background) return color; - switch(type){ - case Type.PRIM: - return color; - case Type.SEC: - return color; - case Type.TERT: - if (isDark(color)) return Colors.WHITE; - else return Colors.BLACK - } - } + const getColor = (): Colors | string | undefined => { + if (color && background) return color; + switch (type) { + case Type.PRIM: + return color; + case Type.SEC: + return color; + case Type.TERT: + if (isDark(color)) return Colors.WHITE; + else return Colors.BLACK; + } + }; - const getBackground = (): Colors | string | undefined => { - if (background) return background; - switch(type){ - case Type.PRIM: - return color; - case Type.SEC: - return color; - case Type.TERT: - return color - } - } + const getBackground = (): Colors | string | undefined => { + if (background) return background; + switch (type) { + case Type.PRIM: + return color; + case Type.SEC: + return color; + case Type.TERT: + return color; + } + }; - const defaultProperties: React.CSSProperties = { - height: getHeight(height, size), - minHeight: getHeight(height, size), - width: fillWidth ? '100%' : width, - padding: undefined, - fontWeight: 500, - fontSize: getFontSize(size), - fontFamily: 'sans-serif', - borderColor: getBorderColor(), - color: getColor() - } + const defaultProperties: React.CSSProperties = { + height: getHeight(height, size), + minHeight: getHeight(height, size), + width: fillWidth ? '100%' : width, + padding: undefined, + fontWeight: 500, + fontSize: getFontSize(size), + fontFamily: 'sans-serif', + borderColor: getBorderColor(), + color: getColor(), + }; - const backgroundProperties: React.CSSProperties = { - background: getBackground() - } + const backgroundProperties: React.CSSProperties = { + background: getBackground(), + }; - const editableText: JSX.Element = ( - <div className={`editableText-container ${type}`} - style={{...defaultProperties, ...style}} - onClick={() => setEditing(true)} - > - {editing ? ( - <input - className={`editableText ${type} ${textAlign}`} - style={{ - height: getHeight(height, size), - textAlign: textAlign, - width: fillWidth ? '100%' : width - }} - placeholder={placeholder} - type={password && !showPassword ? 'password' : undefined} - autoFocus - onChange={handleOnChange} - onKeyPress={handleKeyPress} - onBlur={() => { - !password && setEditing(false) - }} - defaultValue={val} - ></input> - ) : ( - <div - className={`displayText ${type} ${textAlign}`} - style={{ - height: getHeight(height, size), - textAlign: textAlign, - width: fillWidth ? '100%' : width - }} - > - {val ? val : placeholder} + const editableText: JSX.Element = ( + <div className={`editableText-container ${type}`} style={{ ...defaultProperties, ...style }} onClick={() => setEditing(true)}> + {editing ? ( + <input + className={`editableText ${type} ${textAlign}`} + style={{ + height: getHeight(height, size), + textAlign: textAlign, + width: fillWidth ? '100%' : width, + }} + placeholder={placeholder} + type={password && !showPassword ? 'password' : undefined} + autoFocus + onChange={handleOnChange} + onKeyPress={handleKeyPress} + onBlur={() => { + !password && setEditing(false); + }} + defaultValue={val}></input> + ) : ( + <div + className={`displayText ${type} ${textAlign}`} + style={{ + height: getHeight(height, size), + textAlign: textAlign, + width: fillWidth ? '100%' : width, + }}> + {val ? val : placeholder} + </div> + )} + {password && ( + <div className={`password`}> + <Toggle + toggleType={ToggleType.BUTTON} + type={Type.PRIM} + size={size} + color={color} + toggleStatus={showPassword} + onClick={() => setShowPassword(!showPassword)} + tooltip={`${showPassword ? 'Hide' : 'Show'} Password`} + icon={<FaEyeSlash />} + iconFalse={<FaEye />} + /> + </div> + )} + <div className={`editableText-background ${type}`} style={backgroundProperties} /> </div> - )} - {password && <div className={`password`}> - <Toggle - toggleType={ToggleType.BUTTON} - type={Type.PRIM} - size={size} - color={color} - toggleStatus={showPassword} - onClick={() => setShowPassword(!showPassword)} - tooltip={`${showPassword ? 'Hide' : 'Show'} Password`} - icon={<FaEyeSlash/>} - iconFalse={<FaEye/>} - /> - </div>} - <div className={`editableText-background ${type}`} style={backgroundProperties}/> - </div> - ) + ); -return ( - formLabel ? - <div className={`form-wrapper ${formLabelPlacement}`}> - <div className={'formLabel'} style={{fontSize: getFormLabelSize(size)}}>{formLabel}</div> - {editableText} - </div> - : - editableText - ) -} + return formLabel ? ( + <div className={`form-wrapper ${formLabelPlacement}`}> + <div className={'formLabel'} style={{ fontSize: getFormLabelSize(size) }}> + {formLabel} + </div> + {editableText} + </div> + ) : ( + editableText + ); +}; diff --git a/packages/components/src/components/IconButton/IconButton.scss b/packages/components/src/components/IconButton/IconButton.scss index f899dc50f..3f0dd26ea 100644 --- a/packages/components/src/components/IconButton/IconButton.scss +++ b/packages/components/src/components/IconButton/IconButton.scss @@ -45,7 +45,7 @@ &.inactive { .background { - filter: opacity(0) !important; + filter: opacity(0); } } @@ -54,13 +54,13 @@ filter: opacity(0); &.active { - filter: opacity(0.2) !important; + filter: opacity(0.5); } } &:hover { .background { - filter: opacity(0.2); + filter: opacity(0.3); } } } @@ -70,7 +70,7 @@ filter: opacity(0); &.active { - filter: opacity(0.2) !important; + filter: opacity(0.2); } } @@ -85,10 +85,17 @@ &:hover { box-shadow: global.$standard-button-shadow; } + .background { + filter: opacity(0); + + &.active { + filter: opacity(0.5); + } + } &:hover { .background { - filter: brightness(0.8); + filter: opacity(0.3); } } } diff --git a/packages/components/src/components/IconButton/IconButton.tsx b/packages/components/src/components/IconButton/IconButton.tsx index 048048b20..f61f589b9 100644 --- a/packages/components/src/components/IconButton/IconButton.tsx +++ b/packages/components/src/components/IconButton/IconButton.tsx @@ -1,6 +1,6 @@ import { Tooltip } from '@mui/material'; import React from 'react'; -import { Colors, Size, Type, getFontSize, getHeight, isDark, getFormLabelSize } from '../../global'; +import { Colors, Size, Type, getFontSize, getHeight, getFormLabelSize } from '../../global'; import { IButtonProps } from '../Button'; import './IconButton.scss'; @@ -15,6 +15,7 @@ export const IconButton = (props: IButtonProps) => { type = Type.PRIM, color = Colors.MEDIUM_BLUE, background, + filter, label, height, size = Size.SMALL, @@ -71,6 +72,7 @@ export const IconButton = (props: IButtonProps) => { case Type.SEC: return color; case Type.TERT: + return ''; if (colorPicker) return colorPicker; if (active) return color; else return color; @@ -85,12 +87,7 @@ export const IconButton = (props: IButtonProps) => { case Type.SEC: return color; case Type.TERT: - if (colorPicker) { - if (isDark(colorPicker)) return Colors.WHITE; - else return Colors.BLACK; - } - if (isDark(color)) return Colors.WHITE; - else return Colors.BLACK; + return ''; } }; @@ -102,15 +99,14 @@ export const IconButton = (props: IButtonProps) => { case Type.SEC: return color; case Type.TERT: - if (colorPicker) return colorPicker; - else return color; + return ''; //color; } }; const defaultProperties: React.CSSProperties = { - height: getHeight(+(height ?? 0), size), - width: fillWidth ? '100%' : getHeight(+(height ?? 0), size), - minWidth: getHeight(+(height ?? 0), size), + height: getHeight(height, size), + width: fillWidth ? '100%' : getHeight(height, size), + minWidth: getHeight(height, size), fontWeight: 500, fontSize: getFontSize(size, true), borderColor: getBorderColor(), @@ -119,6 +115,7 @@ export const IconButton = (props: IButtonProps) => { const backgroundProperties: React.CSSProperties = { background: getBackground(), + filter, }; const iconButton: JSX.Element = ( @@ -126,9 +123,9 @@ export const IconButton = (props: IButtonProps) => { <div className={`iconButton-container ${type} ${inactive && 'inactive'}`} onClick={handleClick} onDoubleClick={handleDoubleClick} onPointerDown={handlePointerDown} style={{ ...defaultProperties, ...style }} tabIndex={-1}> <div className="iconButton-content"> {icon} - {colorPicker && type !== Type.TERT && <div className={`color`} style={{ background: colorPicker, outlineColor: defaultProperties.color }} />} + {colorPicker && <div className="color" style={{ background: colorPicker, outlineColor: defaultProperties.color }} />} {label && !hideLabel && ( - <div className={'iconButton-label'} style={{ color: defaultProperties.color }}> + <div className="iconButton-label" style={{ color: defaultProperties.color }}> {label} </div> )} @@ -140,7 +137,7 @@ export const IconButton = (props: IButtonProps) => { return formLabel ? ( <div className={`form-wrapper ${formLabelPlacement}`} style={{ width: fillWidth ? '100%' : undefined }}> - <div className={'formLabel'} style={{ fontSize: getFormLabelSize(size) }}> + <div className="formLabel" style={{ fontSize: getFormLabelSize(size) }}> {formLabel} </div> {iconButton} diff --git a/packages/components/src/components/ListItem/ListItem.tsx b/packages/components/src/components/ListItem/ListItem.tsx index e04c6fbee..6bb3e3824 100644 --- a/packages/components/src/components/ListItem/ListItem.tsx +++ b/packages/components/src/components/ListItem/ListItem.tsx @@ -85,7 +85,7 @@ export const ListItem = (props: IListItemProps) => { <div className="listItem-background" style={{ - background: background ? background : style?.color ? style.color : color, + background: background ?? style?.color ?? color, filter: selected ? 'opacity(0.3)' : isHovered && !inactive ? 'opacity(0.2)' : 'opacity(0)', }} /> diff --git a/packages/components/src/components/MultiToggle/MultiToggle.tsx b/packages/components/src/components/MultiToggle/MultiToggle.tsx index 7fff12c8e..0f659c5ca 100644 --- a/packages/components/src/components/MultiToggle/MultiToggle.tsx +++ b/packages/components/src/components/MultiToggle/MultiToggle.tsx @@ -1,29 +1,29 @@ -import * as React from 'react' -import { useState } from 'react' -import { Colors, IGlobalProps, Type } from '../../global' -import { Group } from '../Group' -import { IconButton } from '../IconButton' -import { Popup } from '../Popup' -import { IToggleProps, Toggle, ToggleType } from '../Toggle' +import * as React from 'react'; +import { useState } from 'react'; +import { Colors, IGlobalProps, Type } from '../../global'; +import { Group } from '../Group'; +import { IconButton } from '../IconButton'; +import { Popup } from '../Popup'; +import { IToggleProps, Toggle, ToggleType } from '../Toggle'; export interface IToggleItemProps extends IToggleProps { - val: string + val: string; } export interface IMultiToggleProps extends IGlobalProps { - items: IToggleItemProps[] + items: IToggleItemProps[]; multiSelect?: boolean; - defaultSelectedItems?: (string|number) | ((string|number)[]), - selectedItems?: (string | number) | ((string|number)[]), - onSelectionChange?: (val: (string|number) | (string|number)[], added: boolean) => unknown, + defaultSelectedItems?: (string | number) | (string | number)[]; + selectedItems?: (string | number) | (string | number)[]; + onSelectionChange?: (val: (string | number) | (string | number)[], added: boolean) => unknown; isToggle?: boolean; toggleStatus?: boolean; } -function promoteToArrayOrUndefined(d : (string|number)[]|(string|number)|undefined) { - return d instanceof Array || d === undefined ? d: [d]; +function promoteToArrayOrUndefined(d: (string | number)[] | (string | number) | undefined) { + return d instanceof Array || d === undefined ? d : [d]; } -function promoteToArray(d : (string|number)[]|(string|number)|undefined) { +function promoteToArray(d: (string | number)[] | (string | number) | undefined) { return promoteToArrayOrUndefined(d) ?? []; } @@ -32,56 +32,67 @@ export const MultiToggle = (props: IMultiToggleProps) => { const initVal = (!init ? undefined : promoteToArrayOrUndefined(props.defaultSelectedItems)) ?? promoteToArrayOrUndefined(props.selectedItems) ?? []; init = false; - const [selectedItemsLocal, setSelectedItemsLocal] = useState(initVal as (string|number) | ((string|number)[])); + const [selectedItemsLocal, setSelectedItemsLocal] = useState(initVal as (string | number) | (string | number)[]); const { items, selectedItems = selectedItemsLocal, tooltip, tooltipPlacement = 'top', onSelectionChange, color, background } = props; const itemsMap = new Map(); - items.forEach((item) => itemsMap.set(item.val, item)); - return <div className={`multiToggle-container`}> - <Popup - toggle={props.isToggle? undefined : <div style={{position: "relative"}}> - <IconButton - color={color} - borderColor={background ? color : undefined} - label={props.label} - active={props.toggleStatus} - background={background} - type={color && background ? Type.TERT : undefined} - {...(itemsMap.get(promoteToArray(selectedItems)[0]) ?? {})} - tooltip={tooltip} - tooltipPlacement={tooltipPlacement} - /> - {promoteToArray(selectedItems).length < 2 ? null : - <div style={{position: "absolute", top: "0", left: "0", color: color ?? Colors.MEDIUM_BLUE}}> - + - </div>} - </div>} - isToggle={props.isToggle} - toggleFunc={() => { - const selItem = items.find(item => promoteToArray(selectedItems).includes(item.val)); - selItem && setSelectedItemsLocal([selItem.val]); - }} - type={props.type} - label={props.isToggle ? props.label : undefined} - toggleStatus={props.isToggle ? props.toggleStatus : undefined} - color={color} - popup={<Group padding={5} color={color} columnGap={0} style={{overflow: 'hidden'}}> - {items.map((item, i) => - <Toggle key={i} color={color} icon={item.icon} tooltip={item.tooltip} - toggleStatus={promoteToArray(selectedItems).includes(item.val)} - type={Type.PRIM} - toggleType={ToggleType.BUTTON} - onClick={e => { - const selected = new Set<string|number>(); - promoteToArray(selectedItems).forEach(val => val && selected.add(val)); - const toAdd = !props.multiSelect || !selected.has(item.val) - if (!toAdd) selected.delete(item.val); - else item.val && selected.add(item.val); - onSelectionChange?.(item.val, toAdd); - setSelectedItemsLocal(props.multiSelect ? Array.from(selected) : item.val); - e.stopPropagation(); - }}/> - )} - </Group>} - /> - </div> -}
\ No newline at end of file + items.forEach(item => itemsMap.set(item.val, item)); + return ( + <div className={`multiToggle-container`}> + <Popup + toggle={ + props.isToggle ? undefined : ( + <div style={{ position: 'relative' }}> + <IconButton + color={color} + borderColor={background ? color : undefined} + label={props.label} + active={props.toggleStatus} + background={color} + {...(itemsMap.get(promoteToArray(selectedItems)[0]) ?? {})} + tooltip={tooltip} + tooltipPlacement={tooltipPlacement} + /> + {promoteToArray(selectedItems).length < 2 ? null : <div style={{ position: 'absolute', top: '0', left: '0', color: color ?? Colors.MEDIUM_BLUE }}>+</div>} + </div> + ) + } + isToggle={props.isToggle} + toggleFunc={() => { + const selItem = items.find(item => promoteToArray(selectedItems).includes(item.val)); + selItem && setSelectedItemsLocal([selItem.val]); + }} + type={props.type} + label={props.isToggle ? props.label : undefined} + toggleStatus={props.isToggle ? props.toggleStatus : undefined} + color={color} + background={background} + popup={ + <Group padding={5} color={color} background={background} columnGap={0} style={{ overflow: 'hidden' }}> + {items.map((item, i) => ( + <Toggle + key={i} + color={color} + background={color} + icon={item.icon} + tooltip={item.tooltip} + toggleStatus={promoteToArray(selectedItems).includes(item.val)} + type={Type.PRIM} + toggleType={ToggleType.BUTTON} + onClick={e => { + const selected = new Set<string | number>(); + promoteToArray(selectedItems).forEach(val => val && selected.add(val)); + const toAdd = !props.multiSelect || !selected.has(item.val); + if (!toAdd) selected.delete(item.val); + else item.val && selected.add(item.val); + onSelectionChange?.(item.val, toAdd); + setSelectedItemsLocal(props.multiSelect ? Array.from(selected) : item.val); + e.stopPropagation(); + }} + /> + ))} + </Group> + } + /> + </div> + ); +}; diff --git a/packages/components/src/components/NumberDropdown/NumberDropdown.tsx b/packages/components/src/components/NumberDropdown/NumberDropdown.tsx index 7f12198d5..b5f55bacf 100644 --- a/packages/components/src/components/NumberDropdown/NumberDropdown.tsx +++ b/packages/components/src/components/NumberDropdown/NumberDropdown.tsx @@ -20,11 +20,41 @@ export interface INumberDropdownProps extends INumberProps { export const NumberDropdown = (props: INumberDropdownProps) => { const [numberLoc, setNumberLoc] = useState<number>(0); - const { fillWidth, numberDropdownType = false, color = Colors.MEDIUM_BLUE, type, formLabelPlacement, showPlusMinus, min, max, unit, step = 1, number = numberLoc, setNumber = setNumberLoc, size, formLabel, tooltip } = props; + const { + fillWidth, // + numberDropdownType = false, + color = Colors.MEDIUM_BLUE, + type, + formLabelPlacement, + showPlusMinus, + min, + max, + unit, + background, + step = 1, + number = numberLoc, + setNumber = setNumberLoc, + size, + formLabel, + tooltip, + } = props; const [isOpen, setOpen] = useState<boolean>(false); let toggleText = number.toString(); if (unit) toggleText = toggleText + unit; - let toggle = <Toggle tooltip={tooltip} color={color} fillWidth={fillWidth} type={type} size={size} align={'center'} text={toggleText} toggleType={ToggleType.BUTTON} toggleStatus={isOpen} onPointerDown={() => setOpen(!isOpen)} />; + let toggle = ( + <Toggle + tooltip={tooltip} // + color={color} + fillWidth={fillWidth} + type={type} + size={size} + align="center" + text={toggleText} + toggleType={ToggleType.BUTTON} + toggleStatus={isOpen} + onPointerDown={() => setOpen(!isOpen)} + /> + ); if (showPlusMinus) { toggle = ( @@ -75,23 +105,23 @@ export const NumberDropdown = (props: INumberDropdownProps) => { break; case 'slider': default: - popup = <Slider size={Size.SMALL} unit={unit} multithumb={false} min={min} max={max} step={step} number={number} setNumber={setNumber} />; + popup = <Slider size={Size.SMALL} unit={unit} background={background} multithumb={false} min={min} max={max} step={step} number={number} setNumber={setNumber} />; break; case 'input': - popup = <Slider multithumb={false} min={min} max={max} step={step} number={number} />; + popup = <Slider multithumb={false} min={min} background={background} max={max} step={step} number={number} />; break; } const numberDropdown: JSX.Element = ( - <div className={`numberDropdown-container`} style={{ height: '75%', width: fillWidth ? '100%' : 'fit-content' }}> - <Popup setOpen={setOpen} placement={'bottom'} size={size} isOpen={isOpen} popup={popup} toggle={toggle} fillWidth={fillWidth} color={color} /> + <div className="numberDropdown-container" style={{ height: '75%', width: fillWidth ? '100%' : 'fit-content' }}> + <Popup setOpen={setOpen} placement="bottom" size={size} isOpen={isOpen} popup={popup} toggle={toggle} fillWidth={fillWidth} color={color} background={background} /> </div> ); return formLabel ? ( - <div className={`form-wrapper ${formLabelPlacement}`} style={{ height: '100%', width: fillWidth ? '100%' : undefined }}> + <div className={`form-wrapper ${formLabelPlacement}`} style={{ color, height: '100%', width: fillWidth ? '100%' : undefined }}> {numberDropdown} - <div className="iconButton-label" style={{ fontSize: getFormLabelSize(size) }}> + <div className="iconButton-label" onPointerDown={() => setOpen(!isOpen)} style={{ cursor: 'pointer', height: '25%', fontSize: getFormLabelSize(size) }}> {formLabel} </div> </div> diff --git a/packages/components/src/components/NumberInput/NumberInput.tsx b/packages/components/src/components/NumberInput/NumberInput.tsx index 33573d000..56c61a41e 100644 --- a/packages/components/src/components/NumberInput/NumberInput.tsx +++ b/packages/components/src/components/NumberInput/NumberInput.tsx @@ -1,89 +1,76 @@ -import * as React from 'react' -import { Colors, INumberProps , Type, getFormLabelSize, getHeight } from '../../global' -import './NumberInput.scss' -import { useState } from 'react' -import { Group } from '../Group' -import { Toggle, ToggleType } from '../Toggle' -import { IconButton } from '../IconButton' -import * as fa from 'react-icons/fa' -import { EditableText } from '../EditableText' +import * as React from 'react'; +import { Colors, INumberProps, getFormLabelSize, getHeight } from '../../global'; +import './NumberInput.scss'; +import { useState } from 'react'; +import { Group } from '../Group'; +import { IconButton } from '../IconButton'; +import * as fa from 'react-icons/fa'; +import { EditableText } from '../EditableText'; export interface INumberInputProps extends INumberProps { - showPlusMinus?: boolean + showPlusMinus?: boolean; } export const NumberInput = (props: INumberInputProps) => { - const [numberLoc, setNumberLoc] = useState<number>(10) - const { - color = Colors.MEDIUM_BLUE, - type, - formLabelPlacement, - showPlusMinus, - min, - max, - unit = '', - width, - fillWidth = width ? true : false, - step = 1, - number = numberLoc, - setNumber = setNumberLoc, - size, - formLabel, - tooltip } = - props; + const [numberLoc, setNumberLoc] = useState<number>(10); + const { color = Colors.MEDIUM_BLUE, type, formLabelPlacement, showPlusMinus, min, max, unit = '', width, fillWidth = width ? true : false, step = 1, number = numberLoc, setNumber = setNumberLoc, size, formLabel } = props; + + let input = ( + <EditableText + color={color} + type={type} + size={size} + val={number.toString() + unit} + // width={getHeight(undefined, size)} + textAlign={'center'} + fillWidth={fillWidth} + width={width && width - (showPlusMinus ? +getHeight(undefined, size) * 4 : 0)} + setVal={val => setNumber(!isNaN(Number(val)) ? Number(val) : number)} + /> + ); - let input = <EditableText - color={color} - type={type} - size={size} - val={number.toString() + unit} - // width={getHeight(undefined, size)} - textAlign={'center'} - fillWidth={fillWidth} - width={width && width - (showPlusMinus ? getHeight(undefined, size) * 4 : 0)} - setVal={val => setNumber(!isNaN(Number(val)) ? Number(val) : number)} - />; - if (showPlusMinus) { - input = <Group columnGap={0} style={{overflow: 'hidden'}}> - {input} - <IconButton - size={size} - icon={<fa.FaMinus/>} - color={color} - onClick={(e) => { - e.stopPropagation(); - setNumber(number - step); - }} - inactive={number - step < min} - tooltip={`Subtract ${step}${unit}`} - /> - <IconButton - size={size} - icon={<fa.FaPlus/>} - color={color} - onClick={(e) => { - e.stopPropagation(); - setNumber(number + step); - }} - inactive={number + step > max} - tooltip={`Add ${step}${unit}`} - /> - </Group> + input = ( + <Group columnGap={0} style={{ overflow: 'hidden' }}> + {input} + <IconButton + size={size} + icon={<fa.FaMinus />} + color={color} + onClick={e => { + e.stopPropagation(); + setNumber(number - step); + }} + inactive={number - step < min} + tooltip={`Subtract ${step}${unit}`} + /> + <IconButton + size={size} + icon={<fa.FaPlus />} + color={color} + onClick={e => { + e.stopPropagation(); + setNumber(number + step); + }} + inactive={number + step > max} + tooltip={`Add ${step}${unit}`} + /> + </Group> + ); } - - return ( - formLabel ? - <div className={`form-wrapper ${formLabelPlacement}`} style={{ width: fillWidth ? '100%' : undefined}}> - <div className={'formLabel'} style={{fontSize: getFormLabelSize(size)}}>{formLabel}</div> - <div className={`numberInput-container`} style={{width: fillWidth ? '100%' : 'fit-content'}}> + return formLabel ? ( + <div className={`form-wrapper ${formLabelPlacement}`} style={{ width: fillWidth ? '100%' : undefined }}> + <div className={'formLabel'} style={{ fontSize: getFormLabelSize(size) }}> + {formLabel} + </div> + <div className={`numberInput-container`} style={{ width: fillWidth ? '100%' : 'fit-content' }}> {input} </div> </div> - : - <div className={`numberInput-container`} style={{width: fillWidth ? '100%' : 'fit-content'}}> + ) : ( + <div className={`numberInput-container`} style={{ width: fillWidth ? '100%' : 'fit-content' }}> {input} </div> - ) -}
\ No newline at end of file + ); +}; diff --git a/packages/components/src/components/Popup/Popup.tsx b/packages/components/src/components/Popup/Popup.tsx index 5a58fee29..82e60f343 100644 --- a/packages/components/src/components/Popup/Popup.tsx +++ b/packages/components/src/components/Popup/Popup.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useRef, useState } from 'react'; -import { Colors, IGlobalProps, Placement, Size, isDark } from '../../global'; +import { IGlobalProps, Placement, Size } from '../../global'; import { Toggle, ToggleType } from '../Toggle'; import './Popup.scss'; import { Popper } from '@mui/material'; @@ -57,7 +57,7 @@ export const Popup = (props: IPopupProps) => { height, fillWidth, iconPlacement = 'left', - background = isDark(color) ? Colors.LIGHT_GRAY : Colors.DARK_GRAY, + background, popupContainsPt, } = props; @@ -116,7 +116,7 @@ export const Popup = (props: IPopupProps) => { size={size} type={type} color={color} - background={props.isToggle ? undefined : background} + background={background} toggleType={ToggleType.BUTTON} icon={icon} iconPlacement={iconPlacement} @@ -138,7 +138,7 @@ export const Popup = (props: IPopupProps) => { </div> <Popper open={isOpen} style={{ zIndex: 20000 }} anchorEl={triggerRef.current} placement={placement} modifiers={[]}> <div - className={`popup-container`} + className="popup-container" ref={popperRef} style={{ width, height, background }} tabIndex={-1} diff --git a/packages/components/src/components/Slider/Slider.tsx b/packages/components/src/components/Slider/Slider.tsx index 5af945383..fefc14832 100644 --- a/packages/components/src/components/Slider/Slider.tsx +++ b/packages/components/src/components/Slider/Slider.tsx @@ -52,7 +52,7 @@ export const Slider = (props: ISliderProps) => { const toDecimal = (num: number) => (decimals !== undefined ? Math.round(num * Math.pow(10, decimals)) / Math.pow(10, decimals) : num); const getLeftPos = (locVal: number) => { - const dragger = getHeight(+(height || 0), size); + const dragger = +getHeight(height, size); return ((locVal - min) / (max - min)) * (width - dragger); }; @@ -65,8 +65,8 @@ export const Slider = (props: ISliderProps) => { background: color, color: isDark(color) ? Colors.LIGHT_GRAY : Colors.DARK_GRAY, fontSize: getFontSize(size), - height: getHeight(+(height || 0), size), - width: getHeight(+(height || 0), size), + height: getHeight(height, size), + width: getHeight(height, size), top: 0, }}> <span className="rs-label">{toDecimal(locVal)}</span> @@ -132,7 +132,7 @@ export const Slider = (props: ISliderProps) => { lastEndVal = endNumberLoc; }} style={{ - padding: `5px 0px ${getHeight(+(height || 0), size)}px 0px`, + padding: `5px 0px ${getHeight(height, size)}px 0px`, width: fillWidth ? '100%' : 'fit-content', }}> <div @@ -141,22 +141,22 @@ export const Slider = (props: ISliderProps) => { r && new ResizeObserver(() => setWidth(+(r?.clientWidth ?? 100))).observe(r); setWidth(+(r?.clientWidth ?? 100)); }} - style={{ height: getHeight(+(height || 0), size) }} + style={{ height: getHeight(height, size) }} onPointerDown={onPointerDown}> {ValSlider} <div className="selected-range" style={{ - height: getHeight(+(height || 0), size) / 10, + height: +getHeight(height, size) / 10, background: multithumb ? Colors.LIGHT_GRAY : color, }} /> <div className="range" style={{ - height: getHeight(+(height || 0), size) / 10, + height: +getHeight(height, size) / 10, width: getLeftPos(endNumber) - getLeftPos(number), - left: getLeftPos(number) + getHeight(+(height || 0), size), + left: getLeftPos(number) + +getHeight(height, size), display: multithumb ? undefined : 'none', background: color, }} diff --git a/packages/components/src/components/Toggle/Toggle.tsx b/packages/components/src/components/Toggle/Toggle.tsx index 5cc2ae339..371d00cc1 100644 --- a/packages/components/src/components/Toggle/Toggle.tsx +++ b/packages/components/src/components/Toggle/Toggle.tsx @@ -1,169 +1,170 @@ -import { Tooltip } from '@mui/material' -import React, { useState } from 'react' -import * as bi from 'react-icons/bi' -import { IGlobalProps, Placement, Type , getFormLabelSize } from '../../global' -import { Size } from '../../global/globalEnums' -import { getFontSize, getHeight } from '../../global/globalUtils' -import { Button, IButtonProps } from '../Button' -import { IconButton } from '../IconButton' -import './Toggle.scss' +import { Tooltip } from '@mui/material'; +import React, { useState } from 'react'; +import * as bi from 'react-icons/bi'; +import { Type, getFormLabelSize } from '../../global'; +import { Size } from '../../global/globalEnums'; +import { getFontSize, getHeight } from '../../global/globalUtils'; +import { Button, IButtonProps } from '../Button'; +import { IconButton } from '../IconButton'; +import './Toggle.scss'; export enum ToggleType { - BUTTON = "button", - CHECKBOX = "checkbox", - SWITCH = "switch", + BUTTON = 'button', + CHECKBOX = 'checkbox', + SWITCH = 'switch', } export interface IToggleProps extends IButtonProps { - toggleStatus?: boolean // true -> selected, false -> unselected - toggleType?: ToggleType - iconFalse?: JSX.Element | string + toggleStatus?: boolean; // true -> selected, false -> unselected + toggleType?: ToggleType; + iconFalse?: JSX.Element | string; + triState?: boolean; } export const Toggle = (props: IToggleProps) => { - const [toggleStatusLoc, setToggleStatusLoc] = useState<boolean>(true); - const { - toggleStatus = toggleStatusLoc, - toggleType = ToggleType.CHECKBOX, - type = Type.SEC, - style, - color, - background, - text, - icon, - iconFalse = icon, - height, - inactive, - label, - iconPlacement, - onPointerDown, - onClick, - tooltip, - tooltipPlacement = 'top', - size = Size.SMALL, - formLabel, - formLabelPlacement, - fillWidth, - align - } = props + const [toggleStatusLoc, setToggleStatusLoc] = useState<boolean>(true); + const { + toggleStatus = toggleStatusLoc, + toggleType = ToggleType.CHECKBOX, + type = Type.SEC, + color, + background, + text, + icon, + iconFalse = icon, + height, + inactive, + label, + iconPlacement, + onPointerDown, + onClick, + triState, + tooltip, + tooltipPlacement = 'top', + size = Size.SMALL, + formLabel, + formLabelPlacement, + fillWidth, + align, + } = props; - /** - * Pointer down - * @param e - */ - const handlePointerDown = (e: React.PointerEvent) => { - if (!inactive && onPointerDown){ - e.stopPropagation(); - e.preventDefault(); - onPointerDown(e) - } - } + /** + * Pointer down + * @param e + */ + const handlePointerDown = (e: React.PointerEvent) => { + if (!inactive && onPointerDown) { + e.stopPropagation(); + e.preventDefault(); + onPointerDown(e); + } + }; - /** - * Single click - * @param e - */ - const handleClick = (e: React.MouseEvent) => { - if (toggleStatus === toggleStatusLoc) { - setToggleStatusLoc(!toggleStatus) - } - - if (!inactive && onClick) { - e.stopPropagation(); - e.preventDefault(); - onClick(e); - } - } + /** + * Single click + * @param e + */ + const handleClick = (e: React.MouseEvent) => { + if (toggleStatus === toggleStatusLoc) { + setToggleStatusLoc(!toggleStatus); + } - const defaultProperties = { - height: getHeight(height, size), - borderColor: color - } + if (!inactive && onClick) { + e.stopPropagation(); + e.preventDefault(); + onClick(e); + } + }; - let toggleElement: JSX.Element; + const defaultProperties = { + height: getHeight(height, size), + borderColor: color, + }; - switch(toggleType) { - case ToggleType.BUTTON: - toggleElement = ( - <Button - text={text} - tooltip={tooltip} - icon={toggleStatus ? icon : iconFalse} - onPointerDown={handlePointerDown} - onClick={handleClick} - active={toggleStatus} - type={type} - size={size} - iconPlacement={iconPlacement} - color={color} - background={background} - label={label} - fillWidth={fillWidth} - align={align} - /> - ); - break; - case ToggleType.CHECKBOX: - toggleElement = ( - <IconButton - icon={ - toggleStatus ? <bi.BiCheck/> : undefined - } - tooltip={tooltip} - onPointerDown={handlePointerDown} - onClick={handleClick} - active={toggleStatus} - type={type} - size={size} - color={color} - background={background} - label={label} - fillWidth={fillWidth} - align={align} - /> - ); - break; - case ToggleType.SWITCH: - default: - toggleElement = ( - <Tooltip disableInteractive={true} arrow={true} placement={tooltipPlacement} title={tooltip}> - <div - className={`toggle-container ${toggleType}`} - onPointerDown={handlePointerDown} - onClick={handleClick} - style={{ - width: 2*getHeight(height, size), - ...defaultProperties - }} - > - <div className="toggle-content" style={{ - fontSize: getFontSize(size), - borderColor: color, - left: toggleStatus ? '0%' : `calc(100% - ${getHeight(height, size)}px)` - }}> - <div className="toggle-switch" style={{ - width: getHeight(height, size), - height: getHeight(height, size), - background: color - }}></div> - </div> - <div className={`toggle-background ${toggleStatus && 'active'}`} - style={{ background: color}} - /> - </div> - </Tooltip> - ); - break; - } + let toggleElement: JSX.Element; + switch (toggleType) { + case ToggleType.BUTTON: + toggleElement = ( + <Button + text={text} + tooltip={tooltip} + icon={toggleStatus ? icon : iconFalse} + onPointerDown={handlePointerDown} + onClick={handleClick} + active={toggleStatus} + type={type} + size={size} + iconPlacement={iconPlacement} + color={color} + background={background} + label={label} + fillWidth={fillWidth} + align={align} + filter={triState ? 'opacity(0.2)' : undefined} + /> + ); + break; + case ToggleType.CHECKBOX: + toggleElement = ( + <IconButton + icon={toggleStatus ? <bi.BiCheck /> : undefined} + tooltip={tooltip} + onPointerDown={handlePointerDown} + onClick={handleClick} + active={toggleStatus} + type={type} + size={size} + color={color} + background={background} + label={label} + fillWidth={fillWidth} + align={align} + /> + ); + break; + case ToggleType.SWITCH: + default: + toggleElement = ( + <Tooltip disableInteractive={true} arrow={true} placement={tooltipPlacement} title={tooltip}> + <div + className={`toggle-container ${toggleType}`} + onPointerDown={handlePointerDown} + onClick={handleClick} + style={{ + width: 2 * +getHeight(height, size), + ...defaultProperties, + }}> + <div + className="toggle-content" + style={{ + fontSize: getFontSize(size), + borderColor: color, + left: toggleStatus ? '0%' : `calc(100% - ${getHeight(height, size)}px)`, + }}> + <div + className="toggle-switch" + style={{ + width: getHeight(height, size), + height: getHeight(height, size), + background: color, + }}></div> + </div> + <div className={`toggle-background ${toggleStatus && 'active'}`} style={{ background: color }} /> + </div> + </Tooltip> + ); + break; + } - return ( - formLabel ? - <div className={`form-wrapper ${formLabelPlacement}`}> - <div className={'formLabel'} style={{fontSize: getFormLabelSize(size)}}>{formLabel}</div> - {toggleElement} - </div> - : - toggleElement - ) -} + return formLabel ? ( + <div className={`form-wrapper ${formLabelPlacement}`}> + <div className={'formLabel'} style={{ fontSize: getFormLabelSize(size) }}> + {formLabel} + </div> + {toggleElement} + </div> + ) : ( + toggleElement + ); +}; diff --git a/packages/components/src/global/globalEnums.tsx b/packages/components/src/global/globalEnums.tsx index bdeacccdb..bd82e3c57 100644 --- a/packages/components/src/global/globalEnums.tsx +++ b/packages/components/src/global/globalEnums.tsx @@ -1,52 +1,53 @@ export enum Colors { - BLACK = "#000000", - DARK_GRAY = "#323232", - MEDIUM_GRAY = "#9F9F9F", - LIGHT_GRAY = "#DFDFDF", - WHITE = "#FFFFFF", - MEDIUM_BLUE = "#4476F7", - MEDIUM_BLUE_ALT = "#4476f73d", // REDUCED OPACITY - LIGHT_BLUE = "#BDDDF5", - PINK = "#E0217D", - YELLOW = "#F5D747", - DROP_SHADOW = "#32323215", - ERROR_RED = "#FF9494", - SUCCESS_GREEN = "#4BB543", - TRANSPARENT = "transparent" + BLACK = '#000000', + DARK_GRAY = '#323232', + MEDIUM_GRAY = '#9F9F9F', + LIGHT_GRAY = '#DFDFDF', + WHITE = '#FFFFFF', + MEDIUM_BLUE = '#4476F7', + MEDIUM_BLUE_ALT = '#4476f73d', // REDUCED OPACITY + LIGHT_BLUE = '#BDDDF5', + PINK = '#E0217D', + YELLOW = '#F5D747', + DROP_SHADOW = '#32323215', + ERROR_RED = '#FF9494', + SUCCESS_GREEN = '#4BB543', + TRANSPARENT = 'transparent', } export enum FontSize { - JUMBO_ICON = "5rem", - ICON = "3rem", - HEADER = "1.6rem", - DEFAULT = "1rem", - SECONDARY = "1.3rem", - LABEL = "0.6rem" + JUMBO_ICON = '5rem', + ICON = '3rem', + HEADER = '1.6rem', + DEFAULT = '1rem', + SECONDARY = '1.3rem', + LABEL = '0.6rem', } export enum Padding { - MINIMUM_PADDING = "4px", - SMALL_PADDING = "8px", - MEDIUM_PADDING = "16px", - LARGE_PADDING = "32px", + MINIMUM_PADDING = '4px', + SMALL_PADDING = '8px', + MEDIUM_PADDING = '16px', + LARGE_PADDING = '32px', } export enum IconSizes { - ICON_SIZE = "28px", + ICON_SIZE = '28px', } export enum Borders { - STANDARD = "solid 1px #9F9F9F", - STANDARD_BORDER_RADIUS = '5px' + STANDARD = 'solid 1px #9F9F9F', + STANDARD_BORDER_RADIUS = '5px', } export enum Shadows { - STANDARD_SHADOW = "0px 3px 4px rgba(0, 0, 0, 0.3)" + STANDARD_SHADOW = '0px 3px 4px rgba(0, 0, 0, 0.3)', } export enum Size { - XSMALL = "xsmall", - SMALL = "small", - MEDIUM = "medium", - LARGE = "large" -}
\ No newline at end of file + XXSMALL = 'xxsmall', + XSMALL = 'xsmall', + SMALL = 'small', + MEDIUM = 'medium', + LARGE = 'large', +} diff --git a/packages/components/src/global/globalUtils.tsx b/packages/components/src/global/globalUtils.tsx index 0f1e0adbc..4a1c2cb66 100644 --- a/packages/components/src/global/globalUtils.tsx +++ b/packages/components/src/global/globalUtils.tsx @@ -1,93 +1,88 @@ -import { Size } from './globalEnums' +import { Size } from './globalEnums'; import Color from 'color'; export interface ILocation { - top: number - left: number - width: number - height: number - override?: 'left' | 'bottom' | 'top' | 'right' + top: number; + left: number; + width: number; + height: number; + override?: 'left' | 'bottom' | 'top' | 'right'; } -export const getFormLabelSize = ( - size: Size | undefined, -) => { - switch (size) { - case Size.XSMALL: - return '7px' - case Size.SMALL: - return '10px' - case Size.MEDIUM: - return '13px' - case Size.LARGE: - return '14px' - default: - return '10px' - } -} +export const getFormLabelSize = (size: Size | undefined) => { + switch (size) { + case Size.XXSMALL: + return '6px'; + case Size.XSMALL: + return '7px'; + case Size.SMALL: + return '10px'; + case Size.MEDIUM: + return '13px'; + case Size.LARGE: + return '14px'; + default: + return '10px'; + } +}; -export const getFontSize = ( - size: Size | undefined, - icon?: boolean -) => { - switch (size) { - case Size.XSMALL: - if (icon) return '11px' - return '9px' - case Size.SMALL: - if (icon) return '15px' - return '11px' - case Size.MEDIUM: - if (icon) return '17px' - return '14px' - case Size.LARGE: - if (icon) return '22px' - return '17px' - default: - if (icon) return '15px' - return '12px' - } -} +export const getFontSize = (size: Size | undefined, icon?: boolean) => { + switch (size) { + case Size.XXSMALL: + if (icon) return '10px'; + return '7px'; + case Size.XSMALL: + if (icon) return '11px'; + return '9px'; + case Size.SMALL: + if (icon) return '15px'; + return '11px'; + case Size.MEDIUM: + if (icon) return '17px'; + return '14px'; + case Size.LARGE: + if (icon) return '22px'; + return '17px'; + default: + if (icon) return '15px'; + return '12px'; + } +}; -export const getHeight = ( - height: number | undefined, - size: Size | undefined -) => { - if (height) return height - switch (size) { - case Size.XSMALL: - return 20 - case Size.SMALL: - return 30 - case Size.MEDIUM: - return 40 - case Size.LARGE: - return 50 - default: - return 30 - } -} +export const getHeight = (height: number | string | undefined, size: Size | undefined) => { + if (height) return height; + switch (size) { + case Size.XXSMALL: + return 15; + case Size.XSMALL: + return 20; + case Size.SMALL: + return 30; + case Size.MEDIUM: + return 40; + case Size.LARGE: + return 50; + default: + return 30; + } +}; -export const colorConvert = (color: any) => { - try { - return color ? Color(color.toLowerCase()) : Color('transparent') - } catch (e) { - console.log('COLOR error:', e) - return Color('red') - } -} +export const colorConvert = (color: string) => { + try { + return color ? Color(color.toLowerCase()) : Color('transparent'); + } catch (e) { + console.log('COLOR error:', e); + return Color('red'); + } +}; -export const isDark = (color: any): boolean => { - if (color === undefined) return false - if (color === 'transparent') return false - if (color.startsWith?.('linear')) return false - const nonAlphaColor = color.startsWith('#') - ? (color as string).substring(0, 7) - : color.startsWith('rgba') - ? color.replace(/,.[^,]*\)/, ')').replace('rgba', 'rgb') - : color - const col = colorConvert(nonAlphaColor).rgb() - const colsum = col.red() + col.green() + col.blue() - if (colsum / col.alpha() > 400 || col.alpha() < 0.25) return false - else return true -} +export const isDark = (color: string): boolean => { + if (color === undefined) return false; + if (color === 'transparent') return false; + if (color.startsWith?.('linear')) return false; + const nonAlphaColor = color.startsWith('#') ? (color as string).substring(0, 7) : color.startsWith('rgba') ? color.replace(/,.[^,]*\)/, ')').replace('rgba', 'rgb') : color; + const col = colorConvert(nonAlphaColor).rgb(); + const colsum = col.red() + col.green() + col.blue(); + if (colsum / col.alpha() > 400 || col.alpha() < 0.25) return false; + else return true; +}; |