aboutsummaryrefslogtreecommitdiff
path: root/packages/components/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/components/src')
-rw-r--r--packages/components/src/components/Button/Button.scss15
-rw-r--r--packages/components/src/components/Button/Button.tsx162
-rw-r--r--packages/components/src/components/ColorPicker/ColorPicker.tsx44
-rw-r--r--packages/components/src/components/Dropdown/Dropdown.tsx13
-rw-r--r--packages/components/src/components/DropdownSearch/DropdownSearch.tsx190
-rw-r--r--packages/components/src/components/EditableText/EditableText.tsx309
-rw-r--r--packages/components/src/components/Group/Group.tsx68
-rw-r--r--packages/components/src/components/IconButton/IconButton.scss20
-rw-r--r--packages/components/src/components/IconButton/IconButton.tsx23
-rw-r--r--packages/components/src/components/ListItem/ListItem.tsx2
-rw-r--r--packages/components/src/components/MultiToggle/MultiToggle.stories.tsx125
-rw-r--r--packages/components/src/components/MultiToggle/MultiToggle.tsx155
-rw-r--r--packages/components/src/components/NumberDropdown/NumberDropdown.tsx46
-rw-r--r--packages/components/src/components/NumberInput/NumberInput.tsx137
-rw-r--r--packages/components/src/components/Popup/Popup.tsx67
-rw-r--r--packages/components/src/components/Slider/Slider.tsx16
-rw-r--r--packages/components/src/components/Toggle/Toggle.tsx309
-rw-r--r--packages/components/src/global/globalEnums.tsx67
-rw-r--r--packages/components/src/global/globalUtils.tsx163
19 files changed, 1048 insertions, 883 deletions
diff --git a/packages/components/src/components/Button/Button.scss b/packages/components/src/components/Button/Button.scss
index bbe2e2470..c86db9fad 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,16 @@
filter: opacity(0);
&.active {
- filter: opacity(0.2) !important;
+ filter: opacity(0.3);
}
}
&:hover {
.background {
- filter: opacity(0.2);
+ filter: opacity(0.3);
+ &.active {
+ filter: opacity(0);
+ }
}
}
}
@@ -79,7 +82,7 @@
filter: opacity(0);
&.active {
- filter: opacity(0.2) !important;
+ filter: opacity(0.2);
}
}
@@ -96,12 +99,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 4a63afac2..9b8893452 100644
--- a/packages/components/src/components/Button/Button.tsx
+++ b/packages/components/src/components/Button/Button.tsx
@@ -6,16 +6,30 @@ import { getFontSize, getHeight } from '../../global/globalUtils';
import { IconButton } from '../IconButton';
import './Button.scss';
import { infoState } from '../../../../../src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState';
+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;
@@ -25,6 +39,13 @@ export interface IButtonProps extends IGlobalProps {
align?: Alignment;
filter?: string;
targetState?: infoState
+ // Additional stylization
+ iconPlacement?: Placement;
+ color?: string;
+ colorPicker?: string;
+ uppercase?: boolean;
+ align?: Alignment;
+ filter?: string;
}
export const Button = (props: IButtonProps) => {
@@ -53,10 +74,38 @@ export const Button = (props: IButtonProps) => {
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} />;
}
+ if (!text) {
+ return <IconButton {...props} />;
+ }
/**
* Pointer down
@@ -69,6 +118,17 @@ export const Button = (props: IButtonProps) => {
onPointerDown(e);
}
};
+ /**
+ * Pointer down
+ * @param e
+ */
+ const handlePointerDown = (e: React.PointerEvent) => {
+ if (!inactive && onPointerDown) {
+ e.stopPropagation();
+ e.preventDefault();
+ onPointerDown(e);
+ }
+ };
/**
* In the event that there is a single click
@@ -81,6 +141,17 @@ export const Button = (props: IButtonProps) => {
onClick(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);
+ }
+ };
/**
* Double click
@@ -93,6 +164,17 @@ export const Button = (props: IButtonProps) => {
onDoubleClick(e);
}
};
+ /**
+ * Double click
+ * @param e
+ */
+ const handleDoubleClick = (e: React.MouseEvent) => {
+ if (!inactive && onDoubleClick) {
+ e.stopPropagation();
+ e.preventDefault();
+ onDoubleClick(e);
+ }
+ };
const getBorderColor = (): Colors | string | undefined => {
switch (type) {
@@ -105,6 +187,17 @@ export const Button = (props: IButtonProps) => {
return color;
}
};
+ 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;
+ }
+ };
const getColor = (): Colors | string | undefined => {
if (color && background) return color;
@@ -128,6 +221,16 @@ export const Button = (props: IButtonProps) => {
case Type.TERT:
}
};
+ 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 defaultProperties: React.CSSProperties = {
height: getHeight(height, size),
@@ -142,11 +245,28 @@ export const Button = (props: IButtonProps) => {
borderColor: getBorderColor(),
color: getColor(),
};
+ 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 backgroundProperties: React.CSSProperties = {
background: getBackground(),
filter,
};
+ const backgroundProperties: React.CSSProperties = {
+ background: getBackground(),
+ filter,
+ };
const button: JSX.Element = (
<Tooltip disableInteractive={true} arrow={true} placement={tooltipPlacement} title={tooltip}>
@@ -187,4 +307,44 @@ export const Button = (props: IButtonProps) => {
) : (
button
);
-}; \ No newline at end of file
+};
+ 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 b3456a598..7dcaad5c3 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/Group/Group.tsx b/packages/components/src/components/Group/Group.tsx
index 7abe4a1c7..6275a09dd 100644
--- a/packages/components/src/components/Group/Group.tsx
+++ b/packages/components/src/components/Group/Group.tsx
@@ -1,49 +1,33 @@
-import React from 'react'
-import './Group.scss'
-import { Colors, IGlobalProps, getFontSize, isDark , getFormLabelSize } from '../../global';
+import React from 'react';
+import './Group.scss';
+import { Colors, IGlobalProps, getFontSize, isDark, getFormLabelSize } from '../../global';
export interface IGroupProps extends IGlobalProps {
- children: any
- rowGap?: number;
- columnGap?: number;
- padding?: number | string;
+ children: any;
+ rowGap?: number;
+ columnGap?: number;
+ padding?: number | string;
}
export const Group = (props: IGroupProps) => {
- const {
- children,
- width = '100%',
- rowGap = 5,
- columnGap = 5,
- padding = 0,
- formLabel,
- formLabelPlacement,
- size,
- style,
- color,
- fillWidth
- } = props
+ const { children, width = '100%', rowGap = 5, columnGap = 5, padding = 0, formLabel, formLabelPlacement, size, style, fillWidth } = props;
- const group: JSX.Element =
- (
- <div
- className="group-wrapper"
- style={{ width, padding: padding, ...style }}
- >
- <div className={`group-container`}
- style={{ rowGap, columnGap }}
- >{children}</div>
- </div>
- )
+ const group: JSX.Element = (
+ <div className="group-wrapper" style={{ width, padding: padding, ...style }}>
+ <div className={`group-container`} style={{ rowGap, columnGap }}>
+ {children}
+ </div>
+ </div>
+ );
- return (
- formLabel ?
- <div className={`form-wrapper ${formLabelPlacement}`}
- style={{ width: fillWidth ? '100%' : undefined}}>
- <div className={'formLabel'} style={{fontSize: getFormLabelSize(size)}}>{formLabel}</div>
- {group}
- </div>
- :
- group
- )
-}
+ return formLabel ? (
+ <div className={`form-wrapper ${formLabelPlacement}`} style={{ width: fillWidth ? '100%' : undefined }}>
+ <div className={'formLabel'} style={{ fontSize: getFormLabelSize(size) }}>
+ {formLabel}
+ </div>
+ {group}
+ </div>
+ ) : (
+ group
+ );
+};
diff --git a/packages/components/src/components/IconButton/IconButton.scss b/packages/components/src/components/IconButton/IconButton.scss
index f899dc50f..f95d94ae4 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,16 @@
filter: opacity(0);
&.active {
- filter: opacity(0.2) !important;
+ filter: opacity(0.3);
}
}
&:hover {
.background {
- filter: opacity(0.2);
+ filter: opacity(0.3);
+ &.active {
+ filter: opacity(0);
+ }
}
}
}
@@ -70,7 +73,7 @@
filter: opacity(0);
&.active {
- filter: opacity(0.2) !important;
+ filter: opacity(0.2);
}
}
@@ -85,10 +88,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 954a0ae44..f61f589b9 100644
--- a/packages/components/src/components/IconButton/IconButton.tsx
+++ b/packages/components/src/components/IconButton/IconButton.tsx
@@ -1,11 +1,9 @@
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';
-export interface IIconButtonProps extends IButtonProps {}
-
export const IconButton = (props: IButtonProps) => {
const {
active,
@@ -17,6 +15,7 @@ export const IconButton = (props: IButtonProps) => {
type = Type.PRIM,
color = Colors.MEDIUM_BLUE,
background,
+ filter,
label,
height,
size = Size.SMALL,
@@ -73,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;
@@ -87,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 '';
}
};
@@ -104,8 +99,7 @@ export const IconButton = (props: IButtonProps) => {
case Type.SEC:
return color;
case Type.TERT:
- if (colorPicker) return colorPicker;
- else return color;
+ return ''; //color;
}
};
@@ -121,6 +115,7 @@ export const IconButton = (props: IButtonProps) => {
const backgroundProperties: React.CSSProperties = {
background: getBackground(),
+ filter,
};
const iconButton: JSX.Element = (
@@ -128,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>
)}
@@ -142,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.stories.tsx b/packages/components/src/components/MultiToggle/MultiToggle.stories.tsx
index e71423d7a..b9ba45f72 100644
--- a/packages/components/src/components/MultiToggle/MultiToggle.stories.tsx
+++ b/packages/components/src/components/MultiToggle/MultiToggle.stories.tsx
@@ -1,69 +1,68 @@
-import { Meta, Story } from '@storybook/react'
-import React from 'react'
-import { IMultiToggleProps, MultiToggle } from './MultiToggle'
-import { FaAlignLeft, FaAlignCenter, FaAlignJustify, FaAlignRight } from 'react-icons/fa'
+import { Meta, Story } from '@storybook/react';
+import React from 'react';
+import { IMultiToggleProps, MultiToggle } from './MultiToggle';
+import { FaAlignLeft, FaAlignCenter, FaAlignJustify, FaAlignRight } from 'react-icons/fa';
export default {
- title: 'Dash/MultiToggle',
- component: MultiToggle,
- argTypes: {},
-} as Meta<typeof MultiToggle>
+ title: 'Dash/MultiToggle',
+ component: MultiToggle,
+ argTypes: {},
+} as Meta<typeof MultiToggle>;
-const MultiToggleStory: Story<IMultiToggleProps> = (args) => <MultiToggle {...args} />
-export const MultiToggleOne = MultiToggleStory.bind({})
+const MultiToggleStory: Story<IMultiToggleProps> = args => <MultiToggle {...args} />;
+export const MultiToggleOne = MultiToggleStory.bind({});
MultiToggleOne.args = {
- tooltip: "Text alignment",
- label: "Alignment",
- defaultSelectedItems: "center",
- toggleStatus: true,
- isToggle: false,
- items: [
- {
- icon: <FaAlignLeft/>,
- tooltip: 'Align left',
- val: "left"
- },
- {
- icon: <FaAlignCenter/>,
- tooltip: 'Align center',
- val: "center"
- },
- {
- icon: <FaAlignRight/>,
- tooltip: 'Align right',
- val: "right"
- },
- {
- icon: <FaAlignJustify/>,
- tooltip: 'Justify',
- val: "justify"
- },
- ]
-}
+ tooltip: 'Text alignment',
+ label: 'Alignment',
+ defaultSelectedItems: 'center',
+ toggleStatus: true,
+ items: [
+ {
+ icon: <FaAlignLeft />,
+ tooltip: 'Align left',
+ val: 'left',
+ },
+ {
+ icon: <FaAlignCenter />,
+ tooltip: 'Align center',
+ val: 'center',
+ },
+ {
+ icon: <FaAlignRight />,
+ tooltip: 'Align right',
+ val: 'right',
+ },
+ {
+ icon: <FaAlignJustify />,
+ tooltip: 'Justify',
+ val: 'justify',
+ },
+ ],
+};
-export const MultiToggleTwo = MultiToggleStory.bind({})
+export const MultiToggleTwo = MultiToggleStory.bind({});
MultiToggleTwo.args = {
- tooltip: "Text Tags",
- label: "Tags",
- defaultSelectedItems : ["left"],
- background: "green",
- color: 'white',
- multiSelect: true,
- items: [
- {
- icon: <FaAlignLeft/>,
- tooltip: 'Like',
- val: "left"
- },
- {
- icon: <FaAlignCenter/>,
- tooltip: 'Todo',
- val: "center"
- },
- {
- icon: <FaAlignRight/>,
- tooltip: 'Idea',
- val: "right"
- },
- ]
-}
+ tooltip: 'Text Tags',
+ label: 'Tags',
+ defaultSelectedItems: ['left'],
+ background: 'green',
+ color: 'white',
+ multiSelect: true,
+ items: [
+ {
+ icon: <FaAlignLeft />,
+ tooltip: 'Like',
+ val: 'left',
+ },
+ {
+ icon: <FaAlignCenter />,
+ tooltip: 'Todo',
+ val: 'center',
+ },
+ {
+ icon: <FaAlignRight />,
+ tooltip: 'Idea',
+ val: 'right',
+ },
+ ],
+};
diff --git a/packages/components/src/components/MultiToggle/MultiToggle.tsx b/packages/components/src/components/MultiToggle/MultiToggle.tsx
index 7fff12c8e..c1d610c34 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,
- isToggle?: boolean;
+ defaultSelectedItems?: (string | number) | (string | number)[];
+ selectedItems?: (string | number) | (string | number)[];
+ onSelectionChange?: (val: (string | number) | (string | number)[], added: boolean) => unknown;
toggleStatus?: boolean;
+ showUntilToggle?: boolean; // whether popup stays open when background is clicked. muyst click toggle button tp close it.
}
-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,75 @@ 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 { items, selectedItems = selectedItemsLocal, tooltip, tooltipPlacement = 'top', onSelectionChange, color, background } = props;
+ const [selectedItemsLocal, setSelectedItemsLocal] = useState(initVal as (string | number) | (string | number)[]);
+ const {
+ items, //
+ selectedItems = selectedItemsLocal,
+ tooltip,
+ toggleStatus,
+ 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
+ isOpen={toggleStatus}
+ multitoggle={true} // this is used to indicate that this is a multi toggle, so it can be styled differently in the popup
+ toggle={
+ <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>
+ }
+ showUntilToggle={props.showUntilToggle ?? true}
+ toggleFunc={() => {
+ const selItem = items.find(item => promoteToArray(selectedItems).includes(item.val));
+ selItem && setSelectedItemsLocal([selItem.val]);
+ }}
+ type={props.type}
+ label={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..9e91a75cf 100644
--- a/packages/components/src/components/Popup/Popup.tsx
+++ b/packages/components/src/components/Popup/Popup.tsx
@@ -1,8 +1,9 @@
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';
+import PositionObserver from '@thednp/position-observer';
export enum PopupTrigger {
CLICK = 'click',
@@ -20,13 +21,13 @@ export interface IPopupProps extends IGlobalProps {
toggle?: JSX.Element;
popup: JSX.Element | string | (() => JSX.Element);
trigger?: PopupTrigger;
- toggleStatus?: boolean;
isOpen?: boolean;
setOpen?: (b: boolean) => void;
background?: string;
- isToggle?: boolean;
+ showUntilToggle?: boolean; // whether popup stays open when background is clicked. muyst click toggle button tp close it.
toggleFunc?: () => void;
popupContainsPt?: (x: number, y: number) => boolean;
+ multitoggle?: boolean;
}
/**
@@ -57,20 +58,22 @@ export const Popup = (props: IPopupProps) => {
height,
fillWidth,
iconPlacement = 'left',
- background = isDark(color) ? Colors.LIGHT_GRAY : Colors.DARK_GRAY,
+ background,
+ multitoggle,
popupContainsPt,
} = props;
const triggerRef = useRef(null);
const popperRef = useRef<HTMLDivElement | null>(null);
- const toggleRef = useRef<HTMLDivElement | null>(null);
+ const [toggleRef, setToggleRef] = useState<HTMLDivElement | null>(null);
let timeout = setTimeout(() => {});
const handlePointerAwayDown = (e: PointerEvent) => {
const rect = popperRef.current?.getBoundingClientRect();
- const rect2 = toggleRef.current?.getBoundingClientRect();
+ const rect2 = toggleRef?.getBoundingClientRect();
if (
+ !props.showUntilToggle &&
(!rect2 || !(rect2.left < e.clientX && rect2.top < e.clientY && rect2.right > e.clientX && rect2.bottom > e.clientY)) &&
rect &&
!(rect.left < e.clientX && rect.top < e.clientY && rect.right > e.clientX && rect.bottom > e.clientY) &&
@@ -82,22 +85,36 @@ export const Popup = (props: IPopupProps) => {
}
};
+ let observer: PositionObserver | undefined = undefined;
+ const [previousPosition, setPreviousPosition] = useState<DOMRect | undefined>(toggleRef?.getBoundingClientRect());
+
useEffect(() => {
if (isOpen) {
window.removeEventListener('pointerdown', handlePointerAwayDown, { capture: true });
window.addEventListener('pointerdown', handlePointerAwayDown, { capture: true });
- return () => window.removeEventListener('pointerdown', handlePointerAwayDown, { capture: true });
- }
- }, [isOpen, popupContainsPt]);
-
+ if (toggleRef && multitoggle) {
+ (observer = new PositionObserver(entries => {
+ entries.forEach(entry => {
+ const currentPosition = entry.boundingClientRect;
+ if (Math.floor(currentPosition.top) !== Math.floor(previousPosition?.top ?? 0) || Math.floor(currentPosition.left) !== Math.floor(previousPosition?.left ?? 0)) {
+ // Perform actions when position changes
+ setPreviousPosition(currentPosition); // Update previous position
+ }
+ });
+ })).observe(toggleRef);
+ }
+ return () => {
+ window.removeEventListener('pointerdown', handlePointerAwayDown, { capture: true });
+ observer?.disconnect();
+ };
+ } else observer?.disconnect();
+ }, [isOpen, toggleRef, popupContainsPt]);
return (
<div className={`popup-wrapper ${fillWidth && 'fillWidth'}`}>
<div
- className={`trigger-container ${fillWidth && 'fillWidth'}`}
ref={triggerRef}
- onClick={() => {
- if (trigger === PopupTrigger.CLICK) setOpen(!isOpen);
- }}
+ className={`trigger-container ${fillWidth && 'fillWidth'}`}
+ onClick={() => trigger === PopupTrigger.CLICK && setOpen(!isOpen)}
onPointerEnter={() => {
if (trigger === PopupTrigger.HOVER || trigger === PopupTrigger.HOVER_DELAY) {
clearTimeout(timeout);
@@ -109,42 +126,38 @@ export const Popup = (props: IPopupProps) => {
timeout = setTimeout(() => setOpen(false), 1000);
}
}}>
- {toggle ?? (
- <div ref={toggleRef}>
+ <div className="special" ref={R => setToggleRef(R)}>
+ {toggle ?? (
<Toggle
tooltip={tooltip}
size={size}
type={type}
color={color}
- background={props.isToggle ? undefined : background}
+ background={background}
toggleType={ToggleType.BUTTON}
icon={icon}
iconPlacement={iconPlacement}
text={text}
label={props.label}
- toggleStatus={isOpen || props.toggleStatus}
+ toggleStatus={isOpen}
onClick={() => {
if (trigger === PopupTrigger.CLICK) {
- if (!props.isToggle || props.toggleStatus) {
- setOpen(!isOpen);
- }
+ setOpen(!isOpen);
props.toggleFunc?.();
}
}}
fillWidth={fillWidth}
/>
- </div>
- )}
+ )}
+ </div>
</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}
- onPointerDown={e => {
- e.stopPropagation();
- }}
+ onPointerDown={e => e.stopPropagation()}
onPointerEnter={() => {
if (trigger === PopupTrigger.HOVER || trigger === PopupTrigger.HOVER_DELAY) {
clearTimeout(timeout);
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;
+};