diff --git a/webapp/packages/core-utils/src/TextTools.ts b/webapp/packages/core-utils/src/TextTools.ts index c1cff41b5b..ad5286b97d 100644 --- a/webapp/packages/core-utils/src/TextTools.ts +++ b/webapp/packages/core-utils/src/TextTools.ts @@ -12,6 +12,8 @@ interface IGetWidthOptions { text: string[]; } +const LETTER_SPACING = 0.4; + export const TextTools = { getWidth({ font, container, text }: IGetWidthOptions): number[] { if (container) { @@ -30,6 +32,11 @@ export const TextTools = { const context = canvas.getContext('2d')!; context.font = font; - return text.map(value => context.measureText(value).width); + return text.map(value => { + const width = context.measureText(value).width; + const spacing = (value.length - 1) * LETTER_SPACING; + + return width + spacing; + }); }, }; diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/DataGridTable.tsx b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/DataGridTable.tsx index 73a4120164..7933561aa4 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/DataGridTable.tsx +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/DataGridTable.tsx @@ -430,7 +430,7 @@ export const DataGridTable = observer IconOrImage { - width: 12px; - } - order-button:hover > IconOrImage { - width: 13px; + padding: 0; + margin-left: 8px; } `; diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableColumnHeader.tsx b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableColumnHeader.tsx index 9ec9cb5bc8..f41ee30641 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableColumnHeader.tsx +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableColumnHeader.tsx @@ -54,9 +54,6 @@ const headerStyles = css` border-radius: 50%; border: 1px solid; } - OrderButton { - margin-left: 4px; - } [|dragging] { opacity: 0.5; } diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableIndexColumnHeader.tsx b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableIndexColumnHeader.tsx index 87e766e097..4fd9893c75 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableIndexColumnHeader.tsx +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableIndexColumnHeader.tsx @@ -25,7 +25,7 @@ const styles = css` cursor: auto; width: 10px; position: absolute; - right: 2px; + right: 8px; top: 50%; transform: translateY(-50%); } diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/useTableData.ts b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/useTableData.ts index 212e2a1387..d5be692ca3 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/useTableData.ts +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/useTableData.ts @@ -42,6 +42,15 @@ export const indexColumn: Column = { formatter: IndexFormatter, }; +const COLUMN_PADDING = 16; +const COLUMN_HEADER_ICON_WIDTH = 16; +const COLUMN_HEADER_TEXT_PADDING = 8; +const COLUMN_HEADER_ORDER_PADDING = 8; +const COLUMN_HEADER_ORDER_WIDTH = 16; + +const CELL_VALUE_BORDER = 2; +const FONT = '400 12px Roboto'; + export function useTableData( model: IDatabaseDataModel, resultIndex: number, @@ -72,17 +81,18 @@ export function useTableData( const columnNames = this.format.getHeaders(); const rowStrings = this.format.getLongestCells(); - // TODO: seems better to do not measure container size - // for detecting max columns size, better to use configurable variable - const measuredCells = TextTools.getWidth({ - font: '400 14px Roboto', - text: columnNames.map((cell, i) => { - if (cell.length > (rowStrings[i] || '').length) { - return cell; - } - return rowStrings[i]; - }), - }).map(v => v + 16 + 32 + 20); + const columnsWidth = TextTools.getWidth({ + font: FONT, + text: columnNames, + }).map( + width => + width + COLUMN_PADDING + COLUMN_HEADER_ICON_WIDTH + COLUMN_HEADER_TEXT_PADDING + COLUMN_HEADER_ORDER_PADDING + COLUMN_HEADER_ORDER_WIDTH, + ); + + const cellsWidth = TextTools.getWidth({ + font: FONT, + text: rowStrings, + }).map(width => width + COLUMN_PADDING + CELL_VALUE_BORDER); const columns: Array> = this.columnKeys.map>((col, index) => ({ // key: uuid(), @@ -90,7 +100,7 @@ export function useTableData( columnDataIndex: { index }, name: this.getColumnInfo(col)?.label || '?', editable: true, - width: Math.min(300, measuredCells[index]), + width: Math.min(300, Math.max(columnsWidth[index], cellsWidth[index] ?? 0)), headerRenderer: TableColumnHeader, editorOptions: { onCellKeyDown, diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/styles/themes/_base-react-grid.scss b/webapp/packages/plugin-data-spreadsheet-new/src/styles/themes/_base-react-grid.scss index 5754e79361..c2d40e65a5 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/styles/themes/_base-react-grid.scss +++ b/webapp/packages/plugin-data-spreadsheet-new/src/styles/themes/_base-react-grid.scss @@ -6,11 +6,11 @@ * you may not use this file except in compliance with the License. */ -@import "@cloudbeaver/core-theming/src/styles/branding"; +@import '@cloudbeaver/core-theming/src/styles/branding'; -$edited-color: rgba(255,153,0,0.3); -$added-color: rgba(145,255,0,0.3); -$deleted-color: rgba(255,51,0,0.3); +$edited-color: rgba(255, 153, 0, 0.3); +$added-color: rgba(145, 255, 0, 0.3); +$deleted-color: rgba(255, 51, 0, 0.3); @mixin base-react-grid() { :global { @@ -26,7 +26,7 @@ $deleted-color: rgba(255,51,0,0.3); background-color: rgba(0, 145, 234, 0.2); } - .rdg-cell:global([aria-selected=true]) { + .rdg-cell:global([aria-selected='true']) { box-shadow: inset 0 0 0 1px #0091ea; } @@ -61,6 +61,10 @@ $deleted-color: rgba(255,51,0,0.3); .rdg-table-header__order-button_unordered { color: #c4c4c4; + + &:hover { + color: $mdc-theme-primary; + } } .rdg-header-row { @@ -87,8 +91,8 @@ $deleted-color: rgba(255,51,0,0.3); &:focus { outline: 0; } - - &:global([aria-selected=true]) { + + &:global([aria-selected='true']) { outline: 0; box-shadow: inset 0 0 0 1px #808080; } @@ -103,7 +107,7 @@ $deleted-color: rgba(255,51,0,0.3); } .rdg-cell-custom-selected::before { - content: ""; + content: ''; position: absolute; left: 0; top: 0; diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Table.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Table.tsx index b654ecca54..07357badd9 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Table.tsx +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Table.tsx @@ -50,6 +50,11 @@ const style = css` } `; +const CELL_FONT = '400 12px Roboto'; +const COLUMN_FONT = '700 12px Roboto'; +const CELL_PADDING = 16; +const CELL_BORDER = 2; + interface Props { objects: DBObject[]; truncated?: boolean; @@ -71,15 +76,19 @@ function getMeasuredCells(columns: ObjectPropertyInfo[], rows: DBObject[]) { } } - return TextTools.getWidth({ - font: '400 12px Roboto', - text: columnNames.map((cell, i) => { - if (cell.length >= rowStrings[i].length) { - return cell; - } - return rowStrings[i]; - }), - }).map(v => v + 16 + 8); + const columnsWidth = TextTools.getWidth({ + font: COLUMN_FONT, + text: columnNames, + }).map(width => width + CELL_PADDING + CELL_BORDER); + + const cellsWidth = TextTools.getWidth({ + font: CELL_FONT, + text: rowStrings, + }).map(width => width + CELL_PADDING + CELL_BORDER); + + const widthData = columnNames.map((_, i) => Math.max(columnsWidth[i], cellsWidth[i] ?? 0)); + + return widthData; } const CUSTOM_COLUMNS = [ColumnSelect, ColumnIcon];