@emmveqz/react-components
Version:
Diverse Components for React
129 lines (125 loc) • 5.26 kB
JavaScript
;
//
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importStar(require("react"));
const styled_1 = __importDefault(require("@emotion/styled"));
const ItemsBadge_1 = __importDefault(require("../ItemsBadge"));
//
const Tooltip = styled_1.default.div `
& .tooltip-badge {
max-width: 26px;
}
& .tooltip-content {
background-color: #666;
border-radius: 24px;
color: #f0f0f0;
display: none;
padding: 8px 16px;
position: absolute;
text-align: center;
z-index: 1;
}
&:hover .tooltip-content {
display: block;
}
`;
function getCssStyle(el, prop) {
return globalThis.getComputedStyle(el, null).getPropertyValue(prop);
}
function getCanvasFont(el) {
const fontWeight = getCssStyle(el, 'font-weight') || 'normal';
const fontSize = getCssStyle(el, 'font-size') || '16px';
const fontFamily = getCssStyle(el, 'font-family') || 'Arial';
return `${fontWeight} ${fontSize} ${fontFamily}`;
}
const AutoTrimmedList = (_a) => {
var { items } = _a, props = __rest(_a, ["items"]);
const trailingDots = ', ...';
const containerRef = (0, react_1.useRef)(null);
const [truncateIdx, setTruncateIdx] = (0, react_1.useState)(-1);
const calculateTruncateIdx = (0, react_1.useCallback)(() => {
var _a;
const canvas = globalThis.document.createElement('canvas');
const context = canvas.getContext('2d');
context.font = getCanvasFont(containerRef.current);
const trailingDotsWidth = Math.ceil(context.measureText(trailingDots).width);
const containerWidth = ((_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0;
// 36 = Badge width.
const availableWidth = containerWidth - trailingDotsWidth - 36;
let itemsTotalWidth = 0;
const idx = items.findIndex((item) => {
itemsTotalWidth += Math.ceil(context.measureText(item).width);
return itemsTotalWidth > availableWidth;
});
setTruncateIdx(idx);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
(0, react_1.useLayoutEffect)(() => {
calculateTruncateIdx();
const handleResize = () => {
calculateTruncateIdx();
};
globalThis.addEventListener('resize', handleResize);
return () => {
globalThis.removeEventListener('resize', handleResize);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const isTruncated = truncateIdx > 0;
return (react_1.default.createElement("div", Object.assign({}, props, { ref: containerRef }),
react_1.default.createElement("div", { className: isTruncated ? undefined : 'single-item' },
react_1.default.createElement("span", null, isTruncated
? items.slice(0, truncateIdx).join(', ')
: items.join(', ')),
isTruncated && (react_1.default.createElement("span", null, trailingDots))),
isTruncated && (react_1.default.createElement(Tooltip, null,
react_1.default.createElement("div", { className: "tooltip-badge" },
react_1.default.createElement(ItemsBadge_1.default, { numTruncated: items.length - truncateIdx })),
react_1.default.createElement("div", { className: "tooltip-content" }, items.join(', '))))));
};
exports.default = (0, styled_1.default)(AutoTrimmedList) `
align-items: center;
display: flex;
justify-content: space-between;
& .single-item {
overflow: hidden;
text-overflow: ellipsis;
}
`;