UNPKG

@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
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); } };