({
className,
columns,
data,
keyExtractor,
eachRow,
columnClassName,
}: Props<T>)
| 103 | } |
| 104 | |
| 105 | export function WidgetTable<T>({ |
| 106 | className, |
| 107 | columns, |
| 108 | data, |
| 109 | keyExtractor, |
| 110 | eachRow, |
| 111 | columnClassName, |
| 112 | }: Props<T>) { |
| 113 | const gridTemplateColumns = |
| 114 | columns.length > 1 |
| 115 | ? `1fr ${columns |
| 116 | .slice(1) |
| 117 | .map(() => 'auto') |
| 118 | .join(' ')}` |
| 119 | : '1fr'; |
| 120 | |
| 121 | const containerId = React.useMemo( |
| 122 | () => `widget-table-${Math.random().toString(36).substring(7)}`, |
| 123 | [], |
| 124 | ); |
| 125 | |
| 126 | // Generate CSS for container queries |
| 127 | const containerQueryStyles = React.useMemo(() => { |
| 128 | const styles: string[] = []; |
| 129 | |
| 130 | columns.forEach((column) => { |
| 131 | if ( |
| 132 | column.responsive?.priority !== undefined && |
| 133 | column.responsive.priority > 1 |
| 134 | ) { |
| 135 | // Breakpoints - Priority 2 = 150px, Priority 3 = 250px, etc. |
| 136 | // Less aggressive: columns show at smaller container widths |
| 137 | const minWidth = (column.responsive.priority - 1) * 100 + 50; |
| 138 | // Hide by default by collapsing width and hiding content |
| 139 | // Keep in grid flow but take up minimal space |
| 140 | styles.push( |
| 141 | `.${containerId} .cell[data-priority="${column.responsive.priority}"] { min-width: 0; max-width: 0; padding-left: 0; padding-right: 0; overflow: hidden; visibility: hidden; }`, |
| 142 | `@container (min-width: ${minWidth}px) { .${containerId} .cell[data-priority="${column.responsive.priority}"] { min-width: revert; max-width: revert; padding-left: revert; padding-right: 0.5rem; overflow: revert; visibility: visible !important; } }`, |
| 143 | ); |
| 144 | } else if (column.responsive?.minWidth !== undefined) { |
| 145 | styles.push( |
| 146 | `.${containerId} .cell[data-min-width="${column.responsive.minWidth}"] { min-width: 0; max-width: 0; padding-left: 0; padding-right: 0; overflow: hidden; visibility: hidden; }`, |
| 147 | `@container (min-width: ${column.responsive.minWidth}px) { .${containerId} .cell[data-min-width="${column.responsive.minWidth}"] { min-width: revert; max-width: revert; padding-left: revert; padding-right: 0.5rem; overflow: revert; visibility: visible !important; } }`, |
| 148 | ); |
| 149 | } |
| 150 | }); |
| 151 | |
| 152 | // Ensure last visible cell always has padding-right |
| 153 | styles.push( |
| 154 | `.${containerId} .cell:last-child { padding-right: 1rem !important; }`, |
| 155 | ); |
| 156 | |
| 157 | return styles.length > 0 ? <style>{styles.join('\n')}</style> : null; |
| 158 | }, [columns, containerId]); |
| 159 | |
| 160 | return ( |
| 161 | <div className="w-full overflow-x-auto"> |
| 162 | <div |
nothing calls this directly
no test coverage detected