@adaptabletools/adaptable
Version:
Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
272 lines (271 loc) • 9.92 kB
JavaScript
const DEFAULT_PLACEMENT = {
Horizontal: 'Left',
Vertical: 'Below',
};
const HORIZONTAL_VALUES = ['Left', 'Center', 'Right'];
const VERTICAL_VALUES = ['Above', 'Below', 'Merged'];
const isHorizontal = (value) => typeof value === 'string' && HORIZONTAL_VALUES.includes(value);
const isVertical = (value) => typeof value === 'string' && VERTICAL_VALUES.includes(value);
const sanitizePlacement = (placement) => ({
Horizontal: isHorizontal(placement?.Horizontal)
? placement.Horizontal
: DEFAULT_PLACEMENT.Horizontal,
Vertical: isVertical(placement?.Vertical) ? placement.Vertical : DEFAULT_PLACEMENT.Vertical,
});
const sanitizeCellTextLayout = (layout) => {
const result = {};
if (layout?.CellValue) {
result.CellValue = sanitizePlacement(layout.CellValue);
}
if (layout?.PercentValue) {
result.PercentValue = sanitizePlacement(layout.PercentValue);
}
return result;
};
export const resolveBarStyleCellTextLayout = (props) => sanitizeCellTextLayout(props?.CellTextLayout);
export const hasBarStyleCellTextConfigured = (props) => {
const layout = resolveBarStyleCellTextLayout(props);
return Boolean(layout.CellValue || layout.PercentValue);
};
export const getActiveBarStyleCellTextTokens = (props) => {
const layout = resolveBarStyleCellTextLayout(props);
const tokens = [];
if (layout.CellValue) {
tokens.push('CellValue');
}
if (layout.PercentValue) {
tokens.push('PercentageValue');
}
return tokens;
};
export const mergeBarStyleCellTextProperties = (current, patch) => {
const merged = { ...current, ...patch };
if (merged.CellTextLayout) {
merged.CellTextLayout = sanitizeCellTextLayout(merged.CellTextLayout);
if (!merged.CellTextLayout.CellValue && !merged.CellTextLayout.PercentValue) {
delete merged.CellTextLayout;
}
}
if (!merged.CellTextLayout) {
return undefined;
}
return merged;
};
export const setBarStyleCellTextPlacement = (current, token, placement) => {
const layout = resolveBarStyleCellTextLayout(current);
const next = { ...layout };
const key = token === 'CellValue' ? 'CellValue' : 'PercentValue';
if (placement) {
next[key] = sanitizePlacement(placement);
}
else {
delete next[key];
}
return mergeBarStyleCellTextProperties(current, { CellTextLayout: next });
};
export const patchBarStyleCellTextPlacement = (current, token, patch) => {
const layout = resolveBarStyleCellTextLayout(current);
const key = token === 'CellValue' ? 'CellValue' : 'PercentValue';
const existing = layout[key];
const nextPlacement = {
...(existing ?? DEFAULT_PLACEMENT),
...patch,
};
return setBarStyleCellTextPlacement(current, token, nextPlacement);
};
export const toggleBarStyleCellTextToken = (current, token, show) => {
const layout = resolveBarStyleCellTextLayout(current);
const key = token === 'CellValue' ? 'CellValue' : 'PercentValue';
if (show && !layout[key]) {
return {
CellTextProperties: setBarStyleCellTextPlacement(current, token, DEFAULT_PLACEMENT),
};
}
if (!show && layout[key]) {
return {
CellTextProperties: setBarStyleCellTextPlacement(current, token, undefined),
};
}
return { CellTextProperties: current };
};
export const buildBarStyleCellTextLabels = (props, cellValueLabel, percentageLabel) => {
const layout = resolveBarStyleCellTextLayout(props);
const labels = {};
if (layout.CellValue && cellValueLabel != undefined) {
labels.cellValue = cellValueLabel;
}
if (layout.PercentValue && percentageLabel != undefined) {
labels.percentage = percentageLabel;
}
return labels;
};
export const hasBarStyleCellTextLabels = (labels) => Boolean(labels.cellValue || labels.percentage);
export const joinBarStyleCellTextLabels = (labels) => {
const parts = [];
if (labels.cellValue)
parts.push(labels.cellValue);
if (labels.percentage)
parts.push(labels.percentage);
return parts.join(' ');
};
export const resolveBarStyleCellTextSlots = (props, labels) => {
const layout = resolveBarStyleCellTextLayout(props);
const candidates = [];
if (layout.CellValue && labels.cellValue) {
candidates.push({
placement: sanitizePlacement(layout.CellValue),
text: labels.cellValue,
});
}
if (layout.PercentValue && labels.percentage) {
candidates.push({
placement: sanitizePlacement(layout.PercentValue),
text: labels.percentage,
});
}
const slotMap = new Map();
for (const { placement, text } of candidates) {
const key = `${placement.Vertical}|${placement.Horizontal}`;
const existing = slotMap.get(key);
if (existing) {
existing.parts.push(text);
existing.text = existing.parts.join(' ');
}
else {
slotMap.set(key, {
vertical: placement.Vertical,
horizontal: placement.Horizontal,
parts: [text],
text,
});
}
}
return Array.from(slotMap.values());
};
export const getBarStyleCellTextSlotPresence = (props) => {
const layout = resolveBarStyleCellTextLayout(props);
const verticals = new Set();
if (layout.CellValue)
verticals.add(sanitizePlacement(layout.CellValue).Vertical);
if (layout.PercentValue)
verticals.add(sanitizePlacement(layout.PercentValue).Vertical);
return {
hasAbove: verticals.has('Above'),
hasBelow: verticals.has('Below'),
hasMerged: verticals.has('Merged'),
};
};
const HORIZONTAL_LABEL = {
Left: 'Left',
Center: 'Center',
Right: 'Right',
};
const VERTICAL_LABEL = {
Above: 'Above',
Below: 'Below',
Merged: 'Merged',
};
const formatTokenLabel = (token) => token === 'CellValue' ? 'Cell Value' : 'Percent Value';
const formatPlacementSummary = (placement) => {
const { Horizontal, Vertical } = sanitizePlacement(placement);
return `${VERTICAL_LABEL[Vertical]}-${HORIZONTAL_LABEL[Horizontal]}`;
};
export const formatBarStyleCellTextLayoutSummary = (layout) => {
const parts = [];
if (layout.CellValue) {
parts.push(`${formatTokenLabel('CellValue')}: ${formatPlacementSummary(layout.CellValue)}`);
}
if (layout.PercentValue) {
parts.push(`${formatTokenLabel('PercentageValue')}: ${formatPlacementSummary(layout.PercentValue)}`);
}
return parts.length ? parts.join('; ') : undefined;
};
const HORIZONTAL_FLEX_JUSTIFY = {
Left: 'flex-start',
Center: 'center',
Right: 'flex-end',
};
const HORIZONTAL_TEXT_ALIGN = {
Left: 'left',
Center: 'center',
Right: 'right',
};
const createCellTextRow = (slots, textClassName, compact) => {
const row = document.createElement('div');
row.className = textClassName;
row.style.display = 'flex';
row.style.flexDirection = 'row';
row.style.alignItems = 'center';
row.style.width = '100%';
if (compact) {
row.style.fontSize = '0.75em';
row.style.lineHeight = '1';
}
else {
row.style.lineHeight = '1.2';
}
row.style.flex = '0 0 auto';
row.style.gap = '4px';
for (const horizontal of HORIZONTAL_VALUES) {
const slot = slots.find((s) => s.horizontal === horizontal);
const cell = document.createElement('span');
cell.style.flex = '1';
cell.style.minWidth = '0';
cell.style.textAlign = HORIZONTAL_TEXT_ALIGN[horizontal];
cell.style.display = 'flex';
cell.style.justifyContent = HORIZONTAL_FLEX_JUSTIFY[horizontal];
cell.style.alignItems = 'center';
if (slot) {
cell.textContent = slot.text;
}
row.append(cell);
}
if (!slots.some((s) => String(s.text ?? '').length)) {
row.style.display = 'none';
}
return row;
};
export const mountBarStyleCellText = (args) => {
const { cellTextProperties, labels, wrapperEl, textClassName } = args;
if (!hasBarStyleCellTextConfigured(cellTextProperties) || !hasBarStyleCellTextLabels(labels)) {
return;
}
const slots = resolveBarStyleCellTextSlots(cellTextProperties, labels);
if (!slots.length) {
return;
}
const mergedOverlayEl = args.mergedOverlayEl ?? wrapperEl;
const mergedPointerEventsNone = args.mergedPointerEventsNone ?? mergedOverlayEl === wrapperEl;
const slotsByVertical = {
Above: slots.filter((s) => s.vertical === 'Above'),
Below: slots.filter((s) => s.vertical === 'Below'),
Merged: slots.filter((s) => s.vertical === 'Merged'),
};
const layout = resolveBarStyleCellTextLayout(cellTextProperties);
const compact = Boolean(layout.CellValue &&
layout.PercentValue &&
sanitizePlacement(layout.CellValue).Vertical !==
sanitizePlacement(layout.PercentValue).Vertical);
if (slotsByVertical.Above.length) {
const row = createCellTextRow(slotsByVertical.Above, textClassName, compact);
wrapperEl.prepend(row);
}
if (slotsByVertical.Below.length) {
const row = createCellTextRow(slotsByVertical.Below, textClassName, compact);
wrapperEl.append(row);
}
if (slotsByVertical.Merged.length) {
const row = createCellTextRow(slotsByVertical.Merged, textClassName, compact);
row.style.position = 'absolute';
row.style.top = '50%';
row.style.transform = 'translateY(-50%)';
row.style.left = '0';
row.style.right = '0';
row.style.paddingLeft = '5px';
row.style.paddingRight = '5px';
if (mergedPointerEventsNone) {
row.style.pointerEvents = 'none';
}
mergedOverlayEl.append(row);
}
};