Full document, spreadsheet, slideshow, and diagram tooling
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request 'fix(sheets): grid lines visible over colored cell backgrounds' (#71) from fix/box-shadow-grid-lines into main

scott 82239acc 5e0d71b2

+40 -17
+40 -17
src/sheets/main.ts
··· 556 556 if (r <= freezeR) tdStyle += 'top:' + frozenRowTopOffsets[r] + 'px;'; 557 557 if (c <= freezeC) tdStyle += 'left:' + frozenLeftOffsets[c] + 'px;'; 558 558 559 + // Conditional formatting (computed early so bg can go on td) 560 + const cfResult = evaluateRules(displayValue, cfRules); 561 + const cfStyleStr = buildCfStyle(cfResult); 562 + 563 + // Background on td so inset box-shadow grid lines paint on top 564 + tdStyle += getCellBgStyle(cellData, cfStyleStr); 565 + 559 566 const styleAttr = tdStyle ? ' style="' + tdStyle + '"' : ''; 560 567 let spanAttrs = ''; 561 568 if (mergeInfo && !mergeInfo.hidden) { ··· 569 576 if (isSparklineResult(displayValue)) { 570 577 html += '<div class="cell-display" style="padding:0;overflow:hidden;' + getCellStyle(cellData, '') + '"><canvas class="sparkline-canvas" data-sparkline-id="' + id + '" style="width:100%;height:100%;display:block;"></canvas></div>'; 571 578 } else { 572 - // Conditional formatting 573 - const cfResult = evaluateRules(displayValue, cfRules); 574 - const cfStyleStr = buildCfStyle(cfResult); 575 - 576 579 // Wrap text class 577 580 const wrapClass = cellData?.s?.wrap ? ' cell-wrap' : ''; 578 581 ··· 764 767 }; 765 768 } 766 769 770 + // Resolve background color for a cell (explicit style > CF), returns color string or '' 771 + function getCellBgColor(cellData, cfStyleStr) { 772 + if (cellData?.s?.bg) return cellData.s.bg; 773 + if (cfStyleStr) { 774 + const bgMatch = cfStyleStr.match(/background:([^;]+);/); 775 + if (bgMatch) return bgMatch[1]; 776 + } 777 + return ''; 778 + } 779 + 780 + // Background CSS for the <td> — so inset box-shadow grid lines paint on top of it 781 + function getCellBgStyle(cellData, cfStyleStr) { 782 + const bg = getCellBgColor(cellData, cfStyleStr); 783 + return bg ? 'background:' + bg + ';' : ''; 784 + } 785 + 767 786 function getCellStyle(cellData, cfStyleStr) { 768 787 let style = ''; 769 788 if (cellData?.s) { 770 789 const s = cellData.s; 771 790 if (s.color) style += 'color:' + s.color + ';'; 772 - if (s.bg) style += 'background:' + s.bg + ';'; 791 + // bg is now on the <td>, not .cell-display 773 792 if (s.bold) style += 'font-weight:600;'; 774 793 if (s.italic) style += 'font-style:italic;'; 775 794 if (s.fontSize) style += 'font-size:' + s.fontSize + 'pt;'; ··· 794 813 if (s.borders) style += buildBorderStyle(s.borders); 795 814 if (s.wrap) style += 'white-space:normal;word-wrap:break-word;overflow-wrap:break-word;'; 796 815 } 797 - // Conditional formatting (applied after cell style, does not override explicit bg/color) 798 - if (cfStyleStr && (!cellData?.s?.bg && !cellData?.s?.color)) { 799 - style += cfStyleStr; 800 - } else if (cfStyleStr) { 801 - // CF overrides only missing properties 802 - if (!cellData?.s?.bg && cfStyleStr.includes('background:')) { 803 - const bgMatch = cfStyleStr.match(/background:[^;]+;/); 804 - if (bgMatch) style += bgMatch[0]; 805 - } 806 - if (!cellData?.s?.color && cfStyleStr.includes('color:')) { 807 - const colorMatch = cfStyleStr.match(/(?:^|;)(color:[^;]+;)/); 808 - if (colorMatch) style += colorMatch[1]; 816 + // Conditional formatting — bg is handled by getCellBgStyle on the td; 817 + // only apply non-bg CF styles (color, etc.) here on .cell-display 818 + if (cfStyleStr) { 819 + // Strip background from CF string — it goes on the td via getCellBgStyle 820 + const cfNoBg = cfStyleStr.replace(/background:[^;]+;?/g, ''); 821 + if (cfNoBg) { 822 + if (!cellData?.s?.color && cfNoBg.includes('color:')) { 823 + const colorMatch = cfNoBg.match(/(?:^|;)(color:[^;]+;)/); 824 + if (colorMatch) style += colorMatch[1]; 825 + } else if (!cellData?.s?.color) { 826 + style += cfNoBg; 827 + } 809 828 } 810 829 } 811 830 return style; ··· 1739 1758 displayDiv.innerHTML = '<canvas class="sparkline-canvas" data-sparkline-id="' + id + '" style="width:100%;height:100%;display:block;"></canvas>'; 1740 1759 displayDiv.style.cssText = 'padding:0;overflow:hidden;' + getCellStyle(cellData, ''); 1741 1760 } 1761 + // Background on td for sparklines too 1762 + td.style.background = getCellBgColor(cellData, ''); 1742 1763 hasSparklines = true; 1743 1764 } else { 1744 1765 // Remove sparkline canvas if value is no longer a sparkline ··· 1748 1769 const cfResult = evaluateRules(display, cfRules); 1749 1770 const cfStyleStr = buildCfStyle(cfResult); 1750 1771 displayDiv.style.cssText = getCellStyle(cellData, cfStyleStr); 1772 + // Background on td so inset box-shadow grid lines paint on top 1773 + td.style.background = getCellBgColor(cellData, cfStyleStr); 1751 1774 // Update wrap class 1752 1775 if (cellData?.s?.wrap) displayDiv.classList.add('cell-wrap'); 1753 1776 else displayDiv.classList.remove('cell-wrap');