fix: table issues and improve tables button in editor

This commit is contained in:
swve 2025-01-26 12:43:31 +01:00
parent 31e8eaf0b5
commit ca6a80702a
3 changed files with 157 additions and 31 deletions

View file

@ -27,6 +27,10 @@ import AICanvaToolkit from './AI/AICanvaToolkit'
import EmbedObjects from '@components/Objects/Editor/Extensions/EmbedObjects/EmbedObjects' import EmbedObjects from '@components/Objects/Editor/Extensions/EmbedObjects/EmbedObjects'
import Badges from '@components/Objects/Editor/Extensions/Badges/Badges' import Badges from '@components/Objects/Editor/Extensions/Badges/Badges'
import Buttons from '@components/Objects/Editor/Extensions/Buttons/Buttons' import Buttons from '@components/Objects/Editor/Extensions/Buttons/Buttons'
import Table from '@tiptap/extension-table'
import TableHeader from '@tiptap/extension-table-header'
import TableRow from '@tiptap/extension-table-row'
import TableCell from '@tiptap/extension-table-cell'
interface Editor { interface Editor {
content: string content: string
@ -100,6 +104,12 @@ function Canva(props: Editor) {
editable: isEditable, editable: isEditable,
activity: props.activity, activity: props.activity,
}), }),
Table.configure({
resizable: true,
}),
TableRow,
TableHeader,
TableCell,
], ],
content: props.content, content: props.content,
@ -186,6 +196,53 @@ const CanvaWrapper = styled.div`
list-style-type: decimal; list-style-type: decimal;
} }
table {
border-collapse: collapse;
margin: 0;
overflow: hidden;
table-layout: fixed;
width: 100%;
td,
th {
border: 1px solid rgba(139, 139, 139, 0.4);
box-sizing: border-box;
min-width: 1em;
padding: 6px 8px;
position: relative;
vertical-align: top;
> * {
margin-bottom: 0;
}
}
th {
background-color: rgba(217, 217, 217, 0.4);
font-weight: bold;
text-align: left;
}
.selectedCell:after {
background: rgba(139, 139, 139, 0.2);
content: "";
left: 0; right: 0; top: 0; bottom: 0;
pointer-events: none;
position: absolute;
z-index: 2;
}
.column-resize-handle {
background-color: #8d78eb;
bottom: -2px;
pointer-events: none;
position: absolute;
right: -2px;
top: 0;
width: 4px;
}
}
&:focus { &:focus {
outline: none !important; outline: none !important;
outline-style: none !important; outline-style: none !important;

View file

@ -151,7 +151,6 @@ function Editor(props: Editor) {
immediatelyRender: false, immediatelyRender: false,
}) })
console.log(props.content)
const isMobile = useMediaQuery('(max-width: 767px)') const isMobile = useMediaQuery('(max-width: 767px)')
if (isMobile) { if (isMobile) {

View file

@ -12,6 +12,7 @@ import {
ColumnsIcon, ColumnsIcon,
SectionIcon, SectionIcon,
ContainerIcon, ContainerIcon,
ChevronDownIcon,
} from '@radix-ui/react-icons' } from '@radix-ui/react-icons'
import { import {
AlertCircle, AlertCircle,
@ -24,14 +25,18 @@ import {
Lightbulb, Lightbulb,
MousePointerClick, MousePointerClick,
Sigma, Sigma,
Table,
Tag, Tag,
Tags, Tags,
Video, Video,
} from 'lucide-react' } from 'lucide-react'
import { SiYoutube } from '@icons-pack/react-simple-icons' import { SiYoutube } from '@icons-pack/react-simple-icons'
import ToolTip from '@components/Objects/StyledElements/Tooltip/Tooltip' import ToolTip from '@components/Objects/StyledElements/Tooltip/Tooltip'
import React from 'react'
export const ToolbarButtons = ({ editor, props }: any) => { export const ToolbarButtons = ({ editor, props }: any) => {
const [showTableMenu, setShowTableMenu] = React.useState(false)
if (!editor) { if (!editor) {
return null return null
} }
@ -49,6 +54,34 @@ export const ToolbarButtons = ({ editor, props }: any) => {
} }
} }
const tableOptions = [
{
label: 'Insert new table (3×3)',
icon: <TableIcon />,
action: () => editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run()
},
{
label: 'Add row below',
icon: <RowsIcon />,
action: () => editor.chain().focus().addRowAfter().run()
},
{
label: 'Add column right',
icon: <ColumnsIcon />,
action: () => editor.chain().focus().addColumnAfter().run()
},
{
label: 'Delete current row',
icon: <SectionIcon />,
action: () => editor.chain().focus().deleteRow().run()
},
{
label: 'Delete current column',
icon: <ContainerIcon />,
action: () => editor.chain().focus().deleteColumn().run()
}
]
return ( return (
<ToolButtonsWrapper> <ToolButtonsWrapper>
<ToolBtn onClick={() => editor.chain().focus().undo().run()}> <ToolBtn onClick={() => editor.chain().focus().undo().run()}>
@ -97,35 +130,31 @@ export const ToolbarButtons = ({ editor, props }: any) => {
<option value="5">Heading 5</option> <option value="5">Heading 5</option>
<option value="6">Heading 6</option> <option value="6">Heading 6</option>
</ToolSelect> </ToolSelect>
<DividerVerticalIcon <TableMenuWrapper>
style={{ marginTop: 'auto', marginBottom: 'auto', color: 'grey' }} <ToolBtn
/> onClick={() => setShowTableMenu(!showTableMenu)}
<ToolBtn content={'Create table'} className={showTableMenu ? 'is-active' : ''}
onClick={() => editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run()} >
> <TableIcon width={18} />
<TableIcon/> <ChevronDownIcon />
</ToolBtn> </ToolBtn>
<ToolBtn content={'Insert row'} {showTableMenu && (
onClick={() => editor.chain().focus().addRowAfter().run()} <TableDropdown>
> {tableOptions.map((option, index) => (
<RowsIcon/> <TableMenuItem
</ToolBtn> key={index}
<ToolBtn content={'Insert column'} onClick={() => {
onClick={() => editor.chain().focus().addColumnAfter().run()} option.action()
> setShowTableMenu(false)
<ColumnsIcon/> }}
</ToolBtn> >
<ToolBtn content={'Remove column'} <span className="icon">{option.icon}</span>
onClick={() => editor.chain().focus().deleteColumn().run()} <span className="label">{option.label}</span>
> </TableMenuItem>
<ContainerIcon/> ))}
</ToolBtn> </TableDropdown>
<ToolBtn content={'Remove row'} )}
onClick={() => editor.chain().focus().deleteRow().run()} </TableMenuWrapper>
>
<SectionIcon/>
</ToolBtn>
{/* TODO: fix this : toggling only works one-way */}
<DividerVerticalIcon <DividerVerticalIcon
style={{ marginTop: 'auto', marginBottom: 'auto', color: 'grey' }} style={{ marginTop: 'auto', marginBottom: 'auto', color: 'grey' }}
/> />
@ -285,7 +314,7 @@ const ToolBtn = styled.div`
display: flex; display: flex;
background: rgba(217, 217, 217, 0.24); background: rgba(217, 217, 217, 0.24);
border-radius: 6px; border-radius: 6px;
width: 25px; min-width: 25px;
height: 25px; height: 25px;
padding: 5px; padding: 5px;
margin-right: 5px; margin-right: 5px;
@ -322,3 +351,44 @@ const ToolSelect = styled.select`
font-family: 'DM Sans'; font-family: 'DM Sans';
margin-right: 5px; margin-right: 5px;
` `
const TableMenuWrapper = styled.div`
position: relative;
display: inline-block;
`
const TableDropdown = styled.div`
position: absolute;
top: 100%;
left: 0;
background: white;
border: 1px solid rgba(217, 217, 217, 0.5);
border-radius: 6px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
z-index: 1000;
min-width: 180px;
margin-top: 4px;
`
const TableMenuItem = styled.div`
display: flex;
align-items: center;
padding: 8px 12px;
cursor: pointer;
transition: background 0.2s;
&:hover {
background: rgba(217, 217, 217, 0.24);
}
.icon {
margin-right: 8px;
display: flex;
align-items: center;
}
.label {
font-size: 12px;
font-family: 'DM Sans';
}
`