mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
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:
co-authored by
Aleksey Potsetsuev
dariamarutkina
parent
55077c0ba3
commit
8437519f05
@@ -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,
|
||||
}}
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ const styles = css`
|
||||
overflow: hidden;
|
||||
}
|
||||
menu-container {
|
||||
width: 20px;
|
||||
width: 25px;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
|
||||
+1
@@ -22,6 +22,7 @@ export const cellMenuStyles = css`
|
||||
right: 0px;
|
||||
}
|
||||
MenuTrigger {
|
||||
padding: 0 8px;
|
||||
height: 100%;
|
||||
|
||||
&:before {
|
||||
|
||||
+5
-10
@@ -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;
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
-3
@@ -54,9 +54,6 @@ const headerStyles = css`
|
||||
border-radius: 50%;
|
||||
border: 1px solid;
|
||||
}
|
||||
OrderButton {
|
||||
margin-left: 4px;
|
||||
}
|
||||
[|dragging] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
+1
-1
@@ -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,
|
||||
|
||||
+12
-8
@@ -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;
|
||||
|
||||
+18
-9
@@ -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];
|
||||
|
||||
Reference in New Issue
Block a user