react-icons/io#IoIosClose TypeScript Examples
The following examples show how to use
react-icons/io#IoIosClose.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: InputTypeahead.tsx From hub with Apache License 2.0 | 4 votes |
InputTypeahead = forwardRef((props: Props, ref: Ref<RefInputTypeaheadField>) => {
const inputEl = useRef<HTMLInputElement>(null);
const itemsWrapper = useRef<HTMLDivElement | null>(null);
const [inputValue, setInputValue] = useState('');
const [highlightedText, setHighlightedText] = useState<RegExp | null>(null);
const [highlightedItem, setHighlightedItem] = useState<number | null>(null);
useImperativeHandle(ref, () => ({
reset: () => {
setInputValue('');
},
getValue(): string {
return inputValue;
},
updateValue(newValue: string): void {
setInputValue(newValue);
},
}));
const getVisibleItems = useCallback((): Option[] | null => {
let filteredItems: Option[] = [];
let elements: any[] | null = null;
if (!isNull(highlightedItem)) {
setHighlightedItem(null);
}
if (isUndefined(props.displayItemsInValueLength) || inputValue.length >= props.displayItemsInValueLength) {
filteredItems = props.options.filter((opt: Option) => opt.name.toLowerCase().includes(inputValue.toLowerCase()));
elements = orderBy(
filteredItems,
[
(item: Option) =>
props.selected.hasOwnProperty(item.filterKey) && props.selected[item.filterKey].includes(item.id.toString())
? -1
: 1,
'total',
],
['asc', 'desc']
);
// Scroll top when new visible items are displayed
if (itemsWrapper && itemsWrapper.current) {
itemsWrapper.current.scroll(0, 0);
}
}
return elements;
}, [highlightedItem, props.displayItemsInValueLength, props.options, props.selected, inputValue]);
const getSelectedItems = useCallback((): Option[] => {
let selectedItems: Option[] = [];
Object.keys(props.selected).forEach((fKey: string) => {
props.selected[fKey].forEach((item: string) => {
const selected = props.options.find((opt: Option) => opt.id.toString() === item && opt.filterKey === fKey);
if (!isUndefined(selected)) {
selectedItems.push(selected);
}
});
});
return orderBy(selectedItems, 'total', 'desc');
}, [props.options, props.selected]);
const getOptionName = (name: string): JSX.Element => {
if (!isNull(highlightedText)) {
const stringParts: string[] = compact(name.split(highlightedText));
if (stringParts.length === 1) {
return (
<span
className={classnames({
'fw-bold highlighted': name.toLowerCase() === inputValue.toLowerCase(),
})}
>
{name}
</span>
);
}
return (
<>
{stringParts.map((str: string, index: number) => (
<span
key={`${name}_${index}`}
className={classnames({
'fw-bold highlighted': str.toLowerCase() === inputValue.toLowerCase(),
})}
>
{str}
</span>
))}
</>
);
} else {
return <>{name}</>;
}
};
const [visibleItems, setVisibleItems] = useState<Option[] | null>(null);
const [selectedItems, setSelectedItems] = useState<Option[]>(getSelectedItems());
useEffect(() => {
setVisibleItems(getVisibleItems());
}, [inputValue, props.options]); /* eslint-disable-line react-hooks/exhaustive-deps */
useEffect(() => {
setSelectedItems(getSelectedItems());
}, [getSelectedItems, props.selected]);
const onChange = (e: ChangeEvent<HTMLInputElement>) => {
e.stopPropagation();
e.preventDefault();
setHighlightedItem(null);
setInputValue(e.target.value);
const escapedValue = escapeRegExp(e.target.value.toLowerCase());
setHighlightedText(e.target.value !== '' ? new RegExp(`(${escapedValue})`, 'gi') : null);
};
const onSelect = (filterKey: string, id: string, isSelected: boolean) => {
setHighlightedItem(null);
props.onChange(filterKey, id, !isSelected);
if (props.onChangeSelection) {
props.onChangeSelection();
}
};
const onKeyDown = (e: KeyboardEvent<HTMLInputElement>): void => {
switch (e.key) {
case 'ArrowDown':
updateHighlightedItem('down');
return;
case 'ArrowUp':
updateHighlightedItem('up');
return;
case 'Enter':
if (!isNull(highlightedItem) && visibleItems) {
const item = visibleItems[highlightedItem];
const isSelected =
props.selected.hasOwnProperty(item.filterKey) &&
props.selected[item.filterKey].includes(item.id.toString());
onSelect(item.filterKey, item.id.toString(), isSelected);
}
return;
default:
return;
}
};
const scrollDropdown = (index: number) => {
if (itemsWrapper && itemsWrapper.current) {
const itemsOnScreen = Math.floor(itemsWrapper.current.clientHeight / ITEM_HEIGHT);
if (index + 1 > itemsOnScreen) {
itemsWrapper.current.scroll(0, (index + 1 - itemsOnScreen) * ITEM_HEIGHT);
} else {
itemsWrapper.current.scroll(0, 0);
}
}
};
const updateHighlightedItem = (arrow: 'up' | 'down') => {
if (!isNull(highlightedItem)) {
let newIndex: number = arrow === 'up' ? highlightedItem - 1 : highlightedItem + 1;
if (newIndex > visibleItems!.length - 1) {
newIndex = 0;
}
if (newIndex < 0) {
newIndex = visibleItems!.length - 1;
}
scrollDropdown(newIndex);
setHighlightedItem(newIndex);
} else {
if (visibleItems && visibleItems.length > 0) {
const newIndex = arrow === 'up' ? visibleItems.length - 1 : 0;
scrollDropdown(newIndex);
setHighlightedItem(newIndex);
}
}
};
if (props.options.length === 0) return null;
return (
<>
<div className={`mb-3 input-group-sm ${styles.inputWrapper} ${props.inputWrapperClassName}`}>
<input
ref={inputEl}
type="text"
placeholder={props.placeholder || `Search ${props.label}`}
className={classnames(
'flex-grow-1 form-control',
styles.input,
{ 'ps-3 pe-4': props.searchIcon },
{ 'px-3': isUndefined(props.searchIcon) || !props.searchIcon }
)}
name={`inputTypeahead_${props.label}`}
value={inputValue}
onChange={onChange}
onKeyDown={onKeyDown}
spellCheck="false"
autoFocus={!isUndefined(props.autofocus) && props.autofocus}
/>
{props.searchIcon && <FaSearch className={`text-muted position-absolute ${styles.searchIcon}`} />}
{!isUndefined(props.additionalInfo) && <div className="alert p-0 mt-3">{props.additionalInfo}</div>}
</div>
{selectedItems.length > 0 && props.visibleClear && (
<div className="py-1 border-bottom">
<button
className="btn btn-sm w-100"
onClick={() => {
if (props.onClear) {
props.onClear();
}
}}
aria-label="Clear all"
>
<div className="d-flex flex-row align-items-center text-muted">
<IoIosClose />
<small className="ms-2">Clear all</small>
</div>
</button>
</div>
)}
{visibleItems && (
<>
{visibleItems.length === 0 ? (
<div className={`p-3 text-center ${props.listClassName}`}>
<small className="text-muted">Sorry, no matches found</small>
</div>
) : (
<div className={`${styles.itemsList} ${props.listClassName}`} ref={itemsWrapper}>
{visibleItems.map((opt: Option, index: number) => {
const isSelected =
props.selected.hasOwnProperty(opt.filterKey) &&
props.selected[opt.filterKey].includes(opt.id.toString());
const name = getOptionName(opt.name);
return (
<button
key={`opt_${opt.filterKey}_${opt.id}`}
data-testid="typeaheadDropdownBtn"
className={classnames(
'dropdown-item',
styles.option,
props.optClassName,
{
[styles.selected]: isSelected,
},
{
[styles.highlighted]: index === highlightedItem,
}
)}
onClick={() => {
onSelect(opt.filterKey, opt.id.toString(), isSelected);
if (props.onChangeSelection) {
props.onChangeSelection();
}
}}
aria-label={`${isSelected ? 'Unselect' : 'Select'} option`}
>
<div className="d-flex flex-row align-items-center position-relative">
{isSelected && (
<div className={`position-absolute ${styles.checkMark}`}>
<IoIosCheckmark />
</div>
)}
<InputTypeaheadOptionItem opt={opt} name={name} iconClassName={styles.icon} />
{isSelected && (
<div className={`position-absolute ${styles.close}`}>
<IoIosClose />
</div>
)}
</div>
</button>
);
})}
</div>
)}
</>
)}
</>
);
})
Example #2
Source File: WidgetsGroupModal.tsx From hub with Apache License 2.0 | 4 votes |
WidgetsGroupModal = (props: Props) => {
const widthInput = useRef<RefInputField>(null);
const whiteLabel = isWhiteLabel();
const [theme, setTheme] = useState<string>(DEFAULT_THEME);
const [header, setHeader] = useState<boolean>(false);
const [stars, setStars] = useState<boolean>(true);
const [loading, setLoading] = useState<boolean>(true);
const [color, setColor] = useState<string>(DEFAULT_COLOR);
const [fixedWidth, setFixedWidth] = useState<string | undefined>();
const [groupWrapperWidthOpt, setGroupWrapperWidthOpt] = useState<string>(DEFAULT_WRAPPER_OPTION);
const [isValidCode, setIsValidCode] = useState<boolean>(true);
const onFixedWidthChange = (e: ChangeEvent<HTMLInputElement>) => {
setFixedWidth(e.target.value);
widthInput.current!.checkIsValid().then((res: boolean) => {
setIsValidCode(res);
});
};
const buildWidgetsGroupCode = (): string => {
const code = `<div class="artifacthub-widget-group" data-url="${
window.location.href
}" data-theme="${theme}" data-header="${!header ? 'false' : 'true'}" data-stars="${
!stars ? 'false' : 'true'
}" data-color="${color}" data-responsive="${groupWrapperWidthOpt === 'responsive'}" ${
fixedWidth ? `data-width="${fixedWidth}"` : ''
} data-loading="${loading ? 'true' : 'false'}"></div><script async src="${
window.location.origin
}/artifacthub-widget.js"></script>`;
return code;
};
const [widgetCode, setWidgetCode] = useState<string>(buildWidgetsGroupCode());
const resetValues = () => {
setTheme(DEFAULT_THEME);
setHeader(false);
setLoading(true);
setFixedWidth(undefined);
setColor(DEFAULT_COLOR);
setGroupWrapperWidthOpt(DEFAULT_WRAPPER_OPTION);
setWidgetCode(buildWidgetsGroupCode());
};
const onCloseModal = () => {
props.setOpenStatus(false);
resetValues();
};
const handleColorChange = (color: any) => {
setColor(color.hex);
};
useEffect(() => {
setWidgetCode(buildWidgetsGroupCode());
/* eslint-disable react-hooks/exhaustive-deps */
}, [
theme,
header,
stars,
fixedWidth,
groupWrapperWidthOpt,
color,
loading,
props.visibleWidget,
]); /* eslint-enable react-hooks/exhaustive-deps */
return (
<>
{props.visibleWidget && (
<Modal
modalDialogClassName="fs-6"
header={<div className={`h3 m-2 flex-grow-1 ${styles.title}`}>Widgets group</div>}
onClose={onCloseModal}
open={props.visibleWidget}
>
<div className="w-100 position-relative">
<label className={`form-label fw-bold ${styles.label}`} htmlFor="theme">
Theme
</label>
<div className="d-flex flex-row mb-3">
{THEMES.map((themeOpt: RadioProps) => {
return (
<div className="form-check me-4" key={`radio_theme_${themeOpt.name}`}>
<input
className="form-check-input"
type="radio"
name="theme"
id={themeOpt.name}
value={themeOpt.name}
checked={theme === themeOpt.name}
onChange={() => {
setTheme(themeOpt.name);
}}
required
/>
<label className="form-label text-capitalize form-check-label" htmlFor={themeOpt.name}>
<div className="d-flex flex-row align-items-center">
{themeOpt.icon}
<span className="ms-1">{themeOpt.name}</span>
</div>
</label>
</div>
);
})}
</div>
{!whiteLabel && (
<div className="mt-4 mb-3">
<div className="form-check form-switch ps-0">
<label htmlFor="header" className={`form-check-label fw-bold ${styles.label}`}>
Header
</label>
<input
id="header"
type="checkbox"
className="form-check-input position-absolute ms-2"
value="true"
role="switch"
onChange={() => setHeader(!header)}
checked={header}
/>
</div>
<div className="form-text text-muted mt-2">Display Artifact Hub header at the top of the widget.</div>
</div>
)}
<div className="mt-4 mb-3">
<div className="form-check form-switch ps-0">
<label htmlFor="stars" className={`form-check-label fw-bold ${styles.label}`}>
Stars
</label>
<input
id="stars"
type="checkbox"
className="form-check-input position-absolute ms-2"
value="true"
role="switch"
onChange={() => setStars(!stars)}
checked={stars}
/>
</div>
<div className="form-text text-muted mt-2">Display number of stars given to the package.</div>
</div>
<div className="d-flex flex-row">
<div>
<label className={`form-label fw-bold ${styles.label}`} htmlFor="groupWrapperWidthOpt">
Container width
</label>
<div className="d-flex flex-row">
{WRAPPER_OPTIONS.map((wrapperOpt: RadioProps) => {
return (
<div className="form-check me-4" key={`radio_wrapperOpt_${wrapperOpt.name}`}>
<input
className="form-check-input"
type="radio"
name="groupWrapperWidthOpt"
id={wrapperOpt.name}
value={wrapperOpt.name}
checked={groupWrapperWidthOpt === wrapperOpt.name}
onChange={() => {
if (wrapperOpt.name === 'fixed') {
setFixedWidth((WIDGET_WIDTH * 2).toString());
} else {
setIsValidCode(true);
setFixedWidth(undefined);
}
setGroupWrapperWidthOpt(wrapperOpt.name);
}}
required
/>
<label className="text-capitalize form-check-label" htmlFor={wrapperOpt.name}>
<div className="d-flex flex-row align-items-center">
{wrapperOpt.icon}
<span className="ms-1">{wrapperOpt.name}</span>
</div>
</label>
</div>
);
})}
</div>
</div>
<div className={`position-relative ${styles.inputWrapper}`}>
{groupWrapperWidthOpt === 'fixed' && (
<div className="position-absolute d-flex flex-row">
<InputField
ref={widthInput}
type="number"
name="fixedWidth"
min={380}
className="mb-0"
inputClassName={styles.input}
invalidText={{
default: 'This field is required',
rangeUnderflow: 'The min value is 380',
}}
onChange={onFixedWidthChange}
value={fixedWidth}
validateOnBlur
required
/>
<div className="mt-1 text-muted ms-2">px</div>
</div>
)}
</div>
</div>
<div className="mt-4 mb-3">
<div className="form-check form-switch ps-0">
<label htmlFor="loading" className={`form-check-label fw-bold ${styles.label}`}>
Loading spinner
</label>
<input
id="loading"
type="checkbox"
role="switch"
className="form-check-input position-absolute ms-2"
value="true"
onChange={() => setLoading(!loading)}
checked={loading}
/>
</div>
<div className="form-text text-muted mt-2">Display loading spinner while waiting for search results.</div>
</div>
<div className="mt-4 mb-3">
<div className="d-flex flex-row align-items-center">
<label htmlFor="color" className={`form-label fw-bold mb-0 ${styles.label}`}>
Color
</label>
<div className={`btn btn-sm btn-light border p-1 ms-2 ${styles.colorInputWrapper}`}>
<div
className={styles.colorInput}
style={{
backgroundColor: color,
}}
/>
</div>
{color !== DEFAULT_COLOR && (
<button
className="btn btn-sm btn-link text-muted py-0"
onClick={() => setColor(DEFAULT_COLOR)}
aria-label="Reset to default"
>
<IoIosClose />
<small>Reset to default</small>
</button>
)}
</div>
<div className="form-text text-muted mt-3 mb-2">
Color used for widgets border, header and loading spinner.
</div>
<div className={`pb-2 ${styles.colorPickerWrapper}`}>
<SketchPicker
color={color}
presetColors={PRESET_COLORS}
onChangeComplete={handleColorChange}
disableAlpha
/>
</div>
</div>
<div className="mt-3 mb-2">
<label className={`form-label fw-bold ${styles.label}`}>Code</label>
<div data-testid="block-content" className={`flex-grow-1 me-3 user-select-none ${styles.blockWrapper}`}>
<SyntaxHighlighter
language="text"
style={docco}
customStyle={{
backgroundColor: 'var(--color-1-10)',
}}
>
{widgetCode}
</SyntaxHighlighter>
</div>
<ButtonCopyToClipboard
text={widgetCode}
tooltipClassName={`bs-tooltip-end ${styles.copyBtnTooltip}`}
arrowClassName={styles.copyBtnArrow}
visibleBtnText
contentBtn="Copy code to clipboard"
className="btn-outline-secondary px-2 py-1 text-uppercase"
disabled={!isValidCode}
label="Copy code to clipboard"
/>
</div>
</div>
</Modal>
)}
</>
);
}