@point-api/dropdown-react
Version:
HOC to add a Point API autocomplete dropdown
141 lines • 5.14 kB
JavaScript
import * as React from "react";
import clsx from "clsx";
import { makeStyles } from "@material-ui/core";
const useStyles = makeStyles({
pointSnippet: (props) => ({
margin: 0,
display: 'flex',
flexDirection: 'column',
minHeight: '2rem',
padding: props.compact ? '0.375rem 0.5rem 0.1875rem 0.5rem' : '0.625rem',
alignItems: 'baseline',
justifyContent: 'space-around',
fontSize: '0.8125rem',
borderBottom: '1px solid #dfdfdf',
...(props.active ? { background: '#d8d8d8', cursor: 'pointer' } : {}),
"&:last-child": {
border: 'none',
},
}),
pointSnippetHeader: (props) => ({
display: 'flex',
width: '100%',
flexWrap: 'wrap',
justifyContent: 'flex-end',
marginBottom: props.compact ? '0.125rem' : '0.25rem',
}),
pointSpacer: {
flexGrow: 1
},
pointSnippetName: {
display: 'flex',
fontSize: '0.8125rem',
fontWeight: 500,
letterSpacing: -0.02,
// color: #8c8b8a,
color: '#3f70a4',
marginRight: '0.25rem',
},
pointSnippetContent: {
display: 'flex',
fontSize: '0.8125rem',
fontWeight: 500,
letterSpacing: -0.02,
// lineHeight: 1.125rem, // was too sparse
color: '#35373f',
},
pointSnippetLabel: {
borderRadius: '3px',
marginRight: '0.125rem',
'&.blue': {
backgroundColor: '#e4eafa'
},
'&.red': {
backgroundColor: '#e4eafa'
},
'&.yellow': {
backgroundColor: '#e4eafa'
}
},
pointSnippetLabelText: {
margin: '0.1875rem',
lineHeight: '0.75rem',
fontSize: '0.5625rem',
fontWeight: 700,
letterSpacing: '0.15px',
textTransform: 'uppercase',
'&.blue': {
color: '#5267ae',
},
'&.red': {
color: '#d4118a',
},
'&.yellow': {
color: '#f28300',
}
}
});
const Suggestion = props => {
const { active, compact, onMouseOver, showLabels, snippet } = props;
const classes = useStyles(props);
const COMPACT_MAX_CHARS = 50;
const COMPACT_MAX_LINES = 10; // COMPACT_MAX_CHARS takes precedence anyway
const TEXT_MAX_CHARS = 105;
const TEXT_MAX_LINES = 3;
const ACTIVE_MAX_CHARS = 200;
const ACTIVE_MAX_LINES = 7;
const formatHTMLText = (htmlText) => {
const tempDiv = document.createElement("div");
htmlText = htmlText.replace(/<br( )?(\/)/g, "↵\n");
htmlText = htmlText.replace(/<img.*(\/)/g, "Media 🖼");
tempDiv.innerHTML = htmlText;
const result = tempDiv.innerText || tempDiv.textContent || '';
if (!result && htmlText.length) {
return "Preview unavailable.";
}
else {
return result;
}
};
const fixTextOverflow = (text, active, compact) => {
const maxChars = active ? ACTIVE_MAX_CHARS : (compact ? COMPACT_MAX_CHARS : TEXT_MAX_CHARS);
const maxLines = active ? ACTIVE_MAX_LINES : (compact ? COMPACT_MAX_LINES : TEXT_MAX_LINES);
const originalText = text;
// Limit max characters
if (text.length > maxChars) {
text = text.slice(0, maxChars);
}
// Limit max line count
text = text.split("↵\n", maxLines).join("↵\n");
if (originalText !== text) {
return text + " (…)";
}
else {
return text;
}
};
const onMouseDown = (e) => {
if (e.button !== 0) {
// Only left mouse button
return;
}
e.preventDefault();
e.stopPropagation();
props.onClickSuggestion();
};
const formattedText = formatHTMLText(snippet.content);
const formattedTextTruncated = fixTextOverflow(formattedText, active, compact);
return (React.createElement("li", { className: classes.pointSnippet, onMouseOver: onMouseOver, onMouseDown: onMouseDown },
React.createElement("div", { className: classes.pointSnippetHeader },
React.createElement("div", { className: classes.pointSnippetName }, snippet.name),
React.createElement("div", { className: classes.pointSpacer }),
showLabels && (React.createElement(React.Fragment, null, snippet.labels.map(labelText => (React.createElement("div", { key: labelText, className: clsx(classes.pointSnippetLabel, "blue") },
React.createElement("div", { className: clsx(classes.pointSnippetLabelText, "blue") }, labelText))))))),
React.createElement("div", { className: classes.pointSnippetContent },
!active && compact && (React.createElement(React.Fragment, null, formattedTextTruncated)),
(active || !compact) && formattedTextTruncated.split("↵\n").map((text, idx) => (React.createElement(React.Fragment, { key: idx },
text,
React.createElement("br", null)))))));
};
export default Suggestion;
//# sourceMappingURL=Suggestion.js.map