1
0
Fork 0
mirror of https://github.com/overleaf/overleaf.git synced 2025-02-20 22:21:06 +00:00

Merge pull request from overleaf/mj-table-cell-alignment

[visual] Enable cell alignment in table generator

GitOrigin-RevId: 31be50712fd6b3b1da37b0906965f70618f6a9b3
This commit is contained in:
Mathias Jakobsen 2023-08-14 09:16:44 +01:00 committed by Copybot
parent 56438c32cc
commit 31c285871a
4 changed files with 74 additions and 10 deletions
services/web/frontend/js/features/source-editor/components/table-generator

View file

@ -34,6 +34,7 @@ export type ColumnDefinition = {
alignment: 'left' | 'center' | 'right' | 'paragraph'
borderLeft: number
borderRight: number
content: string
}
export type TableData = {

View file

@ -1,7 +1,8 @@
import { EditorView } from '@codemirror/view'
import { Positions } from '../tabular'
import { ColumnDefinition, Positions } from '../tabular'
import { ChangeSpec } from '@codemirror/state'
import { RowSeparator } from '../utils'
import { RowSeparator, parseColumnSpecifications } from '../utils'
import { TableSelection } from '../contexts/selection-context'
/* eslint-disable no-unused-vars */
export enum BorderTheme {
@ -96,3 +97,46 @@ export const setBorders = (
})
}
}
export const setAlignment = (
view: EditorView,
selection: TableSelection,
alignment: 'left' | 'right' | 'center',
positions: Positions
) => {
const specification = view.state.sliceDoc(
positions.columnDeclarations.from,
positions.columnDeclarations.to
)
const columnSpecification = parseColumnSpecifications(specification)
const { minX, maxX } = selection.normalized()
for (let i = minX; i <= maxX; i++) {
if (selection.isColumnSelected(i, positions.rowPositions.length)) {
if (columnSpecification[i].alignment === alignment) {
continue
}
columnSpecification[i].alignment = alignment
// TODO: This won't work for paragraph, which needs width argument
columnSpecification[i].content = alignment[0]
}
}
const newSpecification = generateColumnSpecification(columnSpecification)
view.dispatch({
changes: [
{
from: positions.columnDeclarations.from,
to: positions.columnDeclarations.to,
insert: newSpecification,
},
],
})
}
const generateColumnSpecification = (columns: ColumnDefinition[]) => {
return columns
.map(
({ borderLeft, borderRight, content }) =>
`${'|'.repeat(borderLeft)}${content}${'|'.repeat(borderRight)}`
)
.join('')
}

View file

@ -4,7 +4,7 @@ import { ToolbarButton } from './toolbar-button'
import { ToolbarButtonMenu } from './toolbar-button-menu'
import { ToolbarDropdown } from './toolbar-dropdown'
import MaterialIcon from '../../../../../shared/components/material-icon'
import { BorderTheme, setBorders } from './commands'
import { BorderTheme, setAlignment, setBorders } from './commands'
import { useCodeMirrorViewContext } from '../../codemirror-editor'
import { useTableContext } from '../contexts/table-context'
@ -87,27 +87,36 @@ export const Toolbar = memo(function Toolbar() {
label="Alignment"
icon="format_align_left"
id="table-generator-align-dropdown"
disabled
disabled={
!selection.isColumnSelected(
selection.from.cell,
positions.rowPositions.length
)
}
>
<ToolbarButton
icon="format_align_left"
id="table-generator-align-left"
label="Left"
command={() => {
setAlignment(view, selection, 'left', positions)
}}
/>
<ToolbarButton
icon="format_align_center"
id="table-generator-align-center"
label="Center"
command={() => {
setAlignment(view, selection, 'center', positions)
}}
/>
<ToolbarButton
icon="format_align_right"
id="table-generator-align-right"
label="Right"
/>
<ToolbarButton
icon="format_align_justify"
id="table-generator-align-justify"
label="Justify"
command={() => {
setAlignment(view, selection, 'right', positions)
}}
/>
</ToolbarButtonMenu>
<ToolbarButton

View file

@ -11,21 +11,26 @@ export type RowPosition = {
hlines: { from: number; to: number }[]
}
function parseColumnSpecifications(specification: string): ColumnDefinition[] {
export function parseColumnSpecifications(
specification: string
): ColumnDefinition[] {
const columns: ColumnDefinition[] = []
let currentAlignment: ColumnDefinition['alignment'] | undefined
let currentBorderLeft = 0
let currentBorderRight = 0
let currentContent = ''
function maybeCommit() {
if (currentAlignment !== undefined) {
columns.push({
alignment: currentAlignment,
borderLeft: currentBorderLeft,
borderRight: currentBorderRight,
content: currentContent,
})
currentAlignment = undefined
currentBorderLeft = 0
currentBorderRight = 0
currentContent = ''
}
}
for (let i = 0; i < specification.length; i++) {
@ -45,18 +50,23 @@ function parseColumnSpecifications(specification: string): ColumnDefinition[] {
}
case 'c':
currentAlignment = 'center'
currentContent += 'c'
break
case 'l':
currentAlignment = 'left'
currentContent += 'l'
break
case 'r':
currentAlignment = 'right'
currentContent += 'r'
break
case 'p': {
currentAlignment = 'paragraph'
currentContent += 'p'
// TODO: Parse these details
while (i < specification.length && specification.charAt(i) !== '}') {
i++
currentContent += specification.charAt(i)
}
break
}