react-icons/bs#BsFillCaretDownFill TypeScript Examples
The following examples show how to use
react-icons/bs#BsFillCaretDownFill.
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: SchemaDefinition.tsx From hub with Apache License 2.0 | 4 votes |
SchemaDefinition = (props: Props) => {
const ref = useRef<HTMLDivElement>(null);
const def = props.def.options[props.def.active];
const getInitialType = (): string | undefined => {
let currentType: string | undefined;
if (def.type) {
if (isArray(def.type)) {
currentType = def.type[0] as string;
} else {
currentType = def.type;
}
} else {
if (def.properties) {
currentType = 'object';
}
}
return currentType;
};
const [activeType, setActiveType] = useState<string | undefined>(getInitialType());
useEffect(() => {
// Scrolls content into view when a definition is expanded
if (props.isExpanded && ref && ref.current) {
ref.current!.scrollIntoView({ block: 'start', inline: 'nearest', behavior: 'smooth' });
}
}, [props.isExpanded, ref]);
useEffect(() => {
setActiveType(getInitialType());
}, [props.def.active, props.def.combinationType]); /* eslint-disable-line react-hooks/exhaustive-deps */
const typeDef = activeType ? SCHEMA_PROPS_PER_TYPE[activeType] : null;
const formatPropValue = (value?: any, required?: string[]): JSX.Element => {
if (isUndefined(value) || isNull(value)) {
return <span className="ms-1">-</span>;
}
switch (typeof value) {
case 'object':
if (isArray(value)) {
return (
<div className="d-flex flex-column ms-3" role="list">
{value.map((el: string) => (
<div key={`it_${el}`} className={`${styles.listItem} position-relative`} role="listitem">
{el}
</div>
))}
</div>
);
} else {
return (
<div className="ms-3" role="list">
{Object.keys(value).map((el: string) => (
<div key={`it_${el}`} className={`${styles.listItem} position-relative`} role="listitem">
{el}:{' '}
<span className="text-muted">
{value[el] && value[el].type
? isArray(value[el].type)
? value[el].type.join(' | ')
: value[el].type
: '-'}
</span>{' '}
{(checkIfPropIsRequiredInSchema(el, def.required) || checkIfPropIsRequiredInSchema(el, required)) && (
<span className={`text-success text-uppercase position-relative ms-2 fw-bold ${styles.xsBadge}`}>
Required
</span>
)}
</div>
))}
</div>
);
}
case 'boolean':
return <span className="ms-1">{value.toString()}</span>;
default:
return <span className="ms-1">{value}</span>;
}
};
const formatDefaultResume = () => {
if (isNull(def.default)) return 'null';
switch (typeof def.default) {
case 'object':
if (isEmpty(def.default)) {
return <span className="ms-1">{props.defaultValue}</span>;
} else {
return (
<>
<FaCheck className="me-1 text-success" />
<small>(please expand for more details)</small>
</>
);
}
default:
return <span className="ms-1">{props.defaultValue}</span>;
}
};
const getItemsDef = (value?: any): JSX.Element => {
if (isUndefined(value) || isNull(value)) return <span className="ms-1">-</span>;
const types = isArray(value) ? value.map((item: any) => item.type) : [value.type];
return (
<>
<span className="ms-1">
{`[${types.join(',')}] `}
{def.uniqueItems && <span className="ms-1">(unique)</span>}
</span>
</>
);
};
const getArrayDesc = (value?: any): JSX.Element => {
if (isUndefined(value)) return <span className="ms-1">-</span>;
const desc = isArray(value) ? value.map((item: any) => item.description) : [value.description];
return <span>{detectLinksInText(desc.join('. '), 'text-break') || '-'}</span>;
};
const getTypeSpecificKeyword = (item: KeywordProp, className?: string): JSX.Element | null => {
const value = (def as any)[item.value as string];
return (
<div
className={classnames('d-flex align-items-baseline', className, {
'flex-column': typeof value === 'object' && item.value !== 'items',
'flex-row': typeof value !== 'object',
'flex-wrap':
item.value === 'items' && !isUndefined(value) && !isNull(value) && !isUndefined(value.properties),
})}
>
<div>
<small className="text-muted text-uppercase">{item.label}</small>:
</div>
{(() => {
switch (item.value) {
case 'items':
return (
<>
{getItemsDef(value)}
{!isUndefined(value) && !isNull(value) && value.type === 'object' && !isUndefined(value.properties) && (
<div className="w-100">
<div>
<small className="text-muted text-uppercase">Properties</small>:
</div>
{formatPropValue(value.properties, value.required)}
</div>
)}
</>
);
default:
return <>{formatPropValue(value)}</>;
}
})()}
</div>
);
};
const changeActivePath = () => {
props.onActivePathChange(!props.isExpanded ? props.path : undefined);
};
return (
<div className="position-relative w-100" ref={ref}>
<div className={styles.contentWrapper}>
<button
className={`btn text-reset text-start p-0 position-relative w-100 ${styles.btn}`}
onClick={changeActivePath}
aria-label={`${props.isExpanded ? 'Hide' : 'Show'} detail`}
>
<div className="d-flex flex-column">
<div className="d-flex flex-row align-items-start">
<div className={`pe-2 text-secondary ${styles.icon}`}>
{props.isExpanded ? <BsFillCaretDownFill /> : <BsFillCaretRightFill />}
</div>
<div className={`d-flex flex-column flex-grow-1 ${styles.content}`}>
{props.def.error || isUndefined(activeType) ? (
<small className={`text-muted text-uppercase ${styles.errorMsg}`}>Raw</small>
) : (
<>
{def.title && (
<div
className={classnames('fw-bold text-truncate', {
[styles.titleWithRequiredLabel]: props.isRequired,
})}
>
{def.title}
</div>
)}
{!isNull(props.def.combinationType) && (
<>
<select
className={classnames(
'w-50 form-select',
styles.select,
{ 'my-2': def.title },
{ 'mb-2': isUndefined(def.title) }
)}
value={props.def.active}
onClick={(e: ReactMouseEvent<HTMLSelectElement, MouseEvent>) => e.stopPropagation()}
onChange={(e: ChangeEvent<HTMLSelectElement>) => {
props.setValue({
...props.def,
active: parseInt(e.target.value),
});
if (!props.isExpanded) {
changeActivePath();
}
}}
>
{props.def.options.map((sch: JSONSchema, index: number) => (
<option value={index} key={`opt_${index}`}>
Option {index + 1}
</option>
))}
</select>
</>
)}
<div className="d-flex flex-row align-items-start w-100">
<div className="text-nowrap">
<small className="text-muted text-uppercase">Type</small>:{' '}
{def.type && isArray(def.type) ? (
<select
aria-label="Type selection"
className={`ms-1 d-inline form-select position-relative ${styles.select} ${styles.selectInLine}`}
value={activeType}
onClick={(e: ReactMouseEvent<HTMLSelectElement, MouseEvent>) => e.stopPropagation()}
onChange={(e: ChangeEvent<HTMLSelectElement>) => {
setActiveType(e.target.value as string);
if (!props.isExpanded) {
changeActivePath();
}
}}
>
{(def.type as string[]).map((type: string, index: number) => (
<option value={type} key={`opt_${index}`}>
{type}
</option>
))}
</select>
) : (
<span className="ms-1 fw-bold">{activeType}</span>
)}
{activeType === 'array' && def.items && <>{getItemsDef(def.items)}</>}
</div>
{!isUndefined(def.default) && (
<div className="ms-3 text-truncate">
<small className="text-muted text-uppercase">Default</small>:{' '}
<span className={`text-truncate ${styles.default}`}>{formatDefaultResume()}</span>
</div>
)}
<div className="ms-auto ps-2">
{props.isRequired && (
<span
className={`badge badge-sm rounded-pill bg-success text-uppercase position-relative ${styles.badge}`}
>
Required
</span>
)}
</div>
</div>
</>
)}
</div>
</div>
</div>
</button>
{props.isExpanded && (
<div className={`${styles.moreInfo} border-top my-2 pt-2`}>
<div className="d-flex flex-column">
{isNull(typeDef) ? (
<div className="mt-2">
<SyntaxHighlighter language="json" style={tomorrowNight}>
{JSON.stringify(def, null, 2)}
</SyntaxHighlighter>
</div>
) : (
<>
<div className="d-flex flex-row align-items-between">
<div className="fw-bold mb-1">Annotations</div>
<div className="ms-auto">
<ButtonCopyToClipboard
text={props.path}
contentBtn="Copy path to clipboard"
className={`btn-link text-muted p-0 ${styles.btnClip}`}
visibleBtnText
label="Copy path to clipboard"
/>
</div>
</div>
<div>
<small className="text-muted text-uppercase">Description</small>:{' '}
<span className="ms-1">
{def.description ? (
<span className="text-break">{detectLinksInText(def.description, styles.descriptionLink)}</span>
) : (
<>
{def.type === 'array' && def.items ? (
<span className={styles.desc}>{getArrayDesc(def.items)}</span>
) : (
<>-</>
)}
</>
)}
</span>
</div>
{!isUndefined(props.defaultValue) && typeof def.default === 'object' && !isEmpty(def.default) && (
<div>
<small className="text-muted text-uppercase">Default</small>: {props.defaultValue}
</div>
)}
{!isUndefined(typeDef) && (
<>
<div className="fw-bold mt-2 mb-1">Constraints</div>
{typeDef.map((keyword: KeywordProp) => (
<Fragment key={keyword.label}>
{isArray(keyword.value) ? (
<>
<div className="d-flex flex-row">
{keyword.value.map((subKeyword: KeywordProp) => (
<Fragment key={subKeyword.label}>
{getTypeSpecificKeyword(subKeyword, 'me-3')}
</Fragment>
))}
</div>
</>
) : (
<>{getTypeSpecificKeyword(keyword)}</>
)}
</Fragment>
))}
<div>
<small className="text-muted text-uppercase">Enum</small>: {formatPropValue(def.enum)}
</div>
</>
)}
</>
)}
</div>
</div>
)}
</div>
</div>
);
}