CB-3434 include letter spacing computation (#1698)

* CB-3434 include letter spacing computation

* CB-3434 measure column names and cell values separately

* CB-3434 fix: styles

* CB-3434 fix: padding

---------

Co-authored-by: Aleksey Potsetsuev <wrouds@gmail.com>
Co-authored-by: dariamarutkina <125263541+dariamarutkina@users.noreply.github.com>
This commit is contained in:
alex
2023-05-30 13:27:52 +03:00
committed by GitHub
co-authored by Aleksey Potsetsuev dariamarutkina
parent 55077c0ba3
commit 8437519f05
10 changed files with 69 additions and 46 deletions
+8 -1
View File
@@ -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;
});
},
};
@@ -430,7 +430,7 @@ export const DataGridTable = observer<IDataPresentationProps<any, IDatabaseResul
className={`cb-react-grid-theme ${className}`}
columns={tableData.columns}
defaultColumnOptions={{
minWidth: 50,
minWidth: 80,
resizable: true,
formatter: CellFormatter,
}}
@@ -36,7 +36,7 @@ const styles = css`
overflow: hidden;
}
menu-container {
width: 20px;
width: 25px;
height: 100%;
box-sizing: border-box;
overflow: hidden;
@@ -22,6 +22,7 @@ export const cellMenuStyles = css`
right: 0px;
}
MenuTrigger {
padding: 0 8px;
height: 100%;
&:before {
@@ -15,22 +15,17 @@ const styles = css`
order-button {
display: flex;
flex-direction: column;
align-content: center;
align-items: center;
justify-content: center;
height: 20px;
width: 20px;
flex-shrink: 0;
height: 28px;
width: 16px;
box-sizing: border-box;
cursor: pointer;
background: transparent;
outline: none;
color: inherit;
}
order-button > IconOrImage {
width: 12px;
}
order-button:hover > IconOrImage {
width: 13px;
padding: 0;
margin-left: 8px;
}
`;
@@ -54,9 +54,6 @@ const headerStyles = css`
border-radius: 50%;
border: 1px solid;
}
OrderButton {
margin-left: 4px;
}
[|dragging] {
opacity: 0.5;
}
@@ -25,7 +25,7 @@ const styles = css`
cursor: auto;
width: 10px;
position: absolute;
right: 2px;
right: 8px;
top: 50%;
transform: translateY(-50%);
}
@@ -42,6 +42,15 @@ export const indexColumn: Column<IResultSetRowKey, any> = {
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<any, IDatabaseResultSet>,
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<Column<IResultSetRowKey, any>> = this.columnKeys.map<Column<IResultSetRowKey, any>>((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,
@@ -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;
@@ -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];