-
-
Notifications
You must be signed in to change notification settings - Fork 72
Issue 118 width behavior #129
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -74,6 +74,10 @@ export default class ControlledTable extends Component<ControlledTableProps> { | |
| this.props.setProps({ active_cell: this.props.selected_cell[0] }); | ||
| } | ||
|
|
||
| this.handleResize(); | ||
| } | ||
|
|
||
| componentWillMount() { | ||
| // Fallback method for paste handling in Chrome | ||
| // when no input element has focused inside the table | ||
| window.addEventListener('resize', this.handleResize); | ||
|
|
@@ -87,14 +91,6 @@ export default class ControlledTable extends Component<ControlledTableProps> { | |
| document.removeEventListener('paste', this.handlePaste); | ||
| } | ||
|
|
||
| componentWillUpdate() { | ||
| const { table_style } = this.props; | ||
|
|
||
| R.forEach(({ selector, rule }) => { | ||
| this.stylesheet.setRule(selector, rule); | ||
| }, table_style); | ||
| } | ||
|
|
||
| componentDidUpdate() { | ||
| this.handleResize(); | ||
| this.handleDropdown(); | ||
|
|
@@ -128,6 +124,12 @@ export default class ControlledTable extends Component<ControlledTableProps> { | |
| handleResize = () => { | ||
| const { r0c0, r0c1, r1c0, r1c1 } = this.refs as { [key: string]: HTMLElement }; | ||
|
|
||
| const { n_fixed_columns, n_fixed_rows, table_style } = this.props; | ||
|
|
||
| R.forEach(({ selector, rule }) => { | ||
| this.stylesheet.setRule(selector, rule); | ||
| }, table_style); | ||
|
|
||
| // Adjust [fixed columns/fixed rows combo] to fixed rows height | ||
| let trs = r0c1.querySelectorAll('tr'); | ||
| r0c0.querySelectorAll('tr').forEach((tr, index) => { | ||
|
|
@@ -152,6 +154,28 @@ export default class ControlledTable extends Component<ControlledTableProps> { | |
|
|
||
| this.stylesheet.setRule('.cell-1-0 tr', `height: ${getComputedStyle(contentTr).height}`); | ||
| } | ||
|
|
||
| // Adjust the width of the fixed row header | ||
| if (n_fixed_rows) { | ||
| r1c1.querySelectorAll('tr:first-of-type td').forEach((td, index) => { | ||
| const width: any = getComputedStyle(td).width; | ||
| this.stylesheet.setRule( | ||
| `.dash-fixed-row:not(.dash-fixed-column) th:nth-of-type(${index + 1})`, | ||
| `width: ${width}; min-width: ${width}; max-width: ${width};` | ||
| ); | ||
| }); | ||
| } | ||
|
|
||
| // Adjust the width of the fixed row / fixed columns header | ||
| if (n_fixed_columns && n_fixed_rows) { | ||
| r1c0.querySelectorAll('tr:first-of-type td').forEach((td, index) => { | ||
| const width: any = getComputedStyle(td).width; | ||
| this.stylesheet.setRule( | ||
| `.dash-fixed-column.dash-fixed-row th:nth-of-type(${index + 1})`, | ||
| `width: ${width}; min-width: ${width}; max-width: ${width};` | ||
| ); | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| get $el() { | ||
|
|
@@ -594,10 +618,6 @@ export default class ControlledTable extends Component<ControlledTableProps> { | |
| `.dash-spreadsheet-inner td.column-${typeIndex}`, | ||
| `width: 30px; max-width: 30px; min-width: 30px;` | ||
| ); | ||
| this.stylesheet.setRule( | ||
| `.dash-spreadsheet-inner th.column-${typeIndex}`, | ||
| `width: 30px; max-width: 30px; min-width: 30px;` | ||
| ); | ||
|
|
||
| ++typeIndex; | ||
| } | ||
|
|
@@ -607,10 +627,6 @@ export default class ControlledTable extends Component<ControlledTableProps> { | |
| `.dash-spreadsheet-inner td.column-${typeIndex}`, | ||
| `width: 30px; max-width: 30px; min-width: 30px;` | ||
| ); | ||
| this.stylesheet.setRule( | ||
| `.dash-spreadsheet-inner th.column-${typeIndex}`, | ||
| `width: 30px; max-width: 30px; min-width: 30px;` | ||
| ); | ||
|
|
||
| ++typeIndex; | ||
| } | ||
|
|
@@ -624,6 +640,7 @@ export default class ControlledTable extends Component<ControlledTableProps> { | |
| `.dash-spreadsheet-inner td.column-${typeIndex}`, | ||
| `width: ${width}; max-width: ${maxWidth}; min-width: ${minWidth};` | ||
| ); | ||
|
|
||
| this.stylesheet.setRule( | ||
| `.dash-spreadsheet-inner th.column-${typeIndex}`, | ||
| `width: ${width}; max-width: ${maxWidth}; min-width: ${minWidth};` | ||
|
|
@@ -707,6 +724,7 @@ export default class ControlledTable extends Component<ControlledTableProps> { | |
| const { | ||
| id, | ||
| columns, | ||
| content_style, | ||
| n_fixed_columns, | ||
| n_fixed_rows, | ||
| row_deletable, | ||
|
|
@@ -719,14 +737,27 @@ export default class ControlledTable extends Component<ControlledTableProps> { | |
| 'dash-spreadsheet-inner', | ||
| 'dash-spreadsheet', | ||
| ...(n_fixed_rows ? ['freeze-top'] : []), | ||
| ...(n_fixed_columns ? ['freeze-left'] : []) | ||
| ...(n_fixed_columns ? ['freeze-left'] : []), | ||
| [`dash-${content_style}`] | ||
| ]; | ||
|
|
||
| const containerClasses = [ | ||
| 'dash-spreadsheet', | ||
| 'dash-spreadsheet-container', | ||
| ...(n_fixed_rows ? ['freeze-top'] : []), | ||
| ...(n_fixed_columns ? ['freeze-left'] : []) | ||
| ...(n_fixed_columns ? ['freeze-left'] : []), | ||
| [`dash-${content_style}`] | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dash-grow or dash-fit, also contract material |
||
| ]; | ||
|
|
||
| const fragmentClasses = [ | ||
| [ | ||
| n_fixed_rows && n_fixed_columns ? 'dash-fixed-row dash-fixed-column' : '', | ||
| n_fixed_rows ? 'dash-fixed-row' : '' | ||
| ], | ||
| [ | ||
| n_fixed_columns ? 'dash-fixed-column' : '', | ||
| 'dash-fixed-content' | ||
| ] | ||
| ]; | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apply dash-* classes that are part of the table contract to the table fragments that are applicable |
||
|
|
||
| const cells = this.getCells(); | ||
|
|
@@ -748,7 +779,7 @@ export default class ControlledTable extends Component<ControlledTableProps> { | |
| >{row.map((cell, columnIndex) => (<div | ||
| key={columnIndex} | ||
| ref={`r${rowIndex}c${columnIndex}`} | ||
| className={`cell cell-${rowIndex}-${columnIndex}`} | ||
| className={`cell cell-${rowIndex}-${columnIndex} ${fragmentClasses[rowIndex][columnIndex]}`} | ||
| >{cell}</div>)) | ||
| }</div>))} | ||
| </div> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,6 @@ | ||
| import React from 'react'; | ||
| import * as R from 'ramda'; | ||
|
|
||
| import Stylesheet from 'core/Stylesheet'; | ||
| import { SortDirection, SortSettings } from 'core/sorting'; | ||
| import multiUpdateSettings from 'core/sorting/multi'; | ||
| import singleUpdateSettings from 'core/sorting/single'; | ||
|
|
@@ -117,7 +116,6 @@ export default class HeaderFactory { | |
| columnRowIndex, | ||
| labels, | ||
| mergeCells, | ||
| n_fixed_columns, | ||
| offset, | ||
| rowSorting, | ||
| virtualization | ||
|
|
@@ -141,16 +139,12 @@ export default class HeaderFactory { | |
| }); | ||
| } | ||
|
|
||
| const visibleColumns = columns.filter(column => !column.hidden); | ||
|
|
||
| return R.filter(column => !!column, columnIndices.map((columnId, spanId) => { | ||
| const c = columns[columnId]; | ||
| if (c.hidden) { | ||
| return null; | ||
| } | ||
|
|
||
| const visibleIndex = visibleColumns.indexOf(c) + offset; | ||
|
|
||
| let colSpan: number; | ||
| if (!mergeCells) { | ||
| colSpan = 1; | ||
|
|
@@ -166,39 +160,21 @@ export default class HeaderFactory { | |
| } | ||
| } | ||
|
|
||
| // This is not efficient and can be improved upon... | ||
| // Fixed columns need to override the default cell behavior when they span multiple columns | ||
| // Find all columns that fit the header's range [index, index+colspan[ and keep the fixed/visible ones | ||
| const visibleColumnId = visibleColumns.indexOf(c); | ||
|
|
||
| const spannedColumns = visibleColumns.filter((column, index) => | ||
| !column.hidden && | ||
| index >= visibleColumnId && | ||
| index < visibleColumnId + colSpan && | ||
| index + offset < n_fixed_columns | ||
| ); | ||
|
|
||
| // Calculate the width of all those columns combined | ||
| const width = `calc(${spannedColumns.map(column => Stylesheet.unit(column.width || DEFAULT_CELL_WIDTH, 'px')).join(' + ')})`; | ||
| const maxWidth = `calc(${spannedColumns.map(column => Stylesheet.unit(column.maxWidth || column.width || DEFAULT_CELL_WIDTH, 'px')).join(' + ')})`; | ||
| const minWidth = `calc(${spannedColumns.map(column => Stylesheet.unit(column.minWidth || column.width || DEFAULT_CELL_WIDTH, 'px')).join(' + ')})`; | ||
|
|
||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All of these are not applicable anymore and taken care of by the new sync style above |
||
| return (<th | ||
| key={`header-cell-${columnId}`} | ||
| colSpan={colSpan} | ||
| className={ | ||
| `column-${columnId + offset} ` + | ||
| (columnId === columns.length - 1 || columnId === R.last(columnIndices) ? 'cell--right-last ' : '') | ||
| } | ||
| style={visibleIndex < n_fixed_columns ? { maxWidth, minWidth, width } : undefined} | ||
| > | ||
| {rowSorting ? ( | ||
| <span | ||
| className='sort' | ||
| onClick={HeaderFactory.doSort(c.id, options)} | ||
| > | ||
| {HeaderFactory.getSortingIcon(c.id, options)} | ||
| </span>) : ('') | ||
| </span>) : '' | ||
| } | ||
|
|
||
| {((c.editable_name && R.type(c.editable_name) === 'Boolean') || | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -150,6 +150,17 @@ | |
| } | ||
| } | ||
|
|
||
| &.dash-grow { | ||
| .cell-0-1, | ||
| .cell-1-1 { | ||
| flex: 1 0 auto; | ||
| } | ||
|
|
||
| table { | ||
| width: 100%; | ||
| } | ||
| } | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When content_style='grow' we want the right side of the table (non-frozen columns) to fill the available space. |
||
|
|
||
| &:not(.freeze-top):not(.freeze-left) { | ||
| .cell-1-1 { | ||
| .top-left-cells(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default table behavior is to take as little space as possible (fit) but for % based columns and it sometimes (always?) desirable to fill the dash-table container (grow)