mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +00:00
fix: table issues and improve tables button in editor
This commit is contained in:
parent
31e8eaf0b5
commit
ca6a80702a
3 changed files with 157 additions and 31 deletions
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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/>
|
<TableIcon width={18} />
|
||||||
|
<ChevronDownIcon />
|
||||||
</ToolBtn>
|
</ToolBtn>
|
||||||
<ToolBtn content={'Insert row'}
|
{showTableMenu && (
|
||||||
onClick={() => editor.chain().focus().addRowAfter().run()}
|
<TableDropdown>
|
||||||
|
{tableOptions.map((option, index) => (
|
||||||
|
<TableMenuItem
|
||||||
|
key={index}
|
||||||
|
onClick={() => {
|
||||||
|
option.action()
|
||||||
|
setShowTableMenu(false)
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<RowsIcon/>
|
<span className="icon">{option.icon}</span>
|
||||||
</ToolBtn>
|
<span className="label">{option.label}</span>
|
||||||
<ToolBtn content={'Insert column'}
|
</TableMenuItem>
|
||||||
onClick={() => editor.chain().focus().addColumnAfter().run()}
|
))}
|
||||||
>
|
</TableDropdown>
|
||||||
<ColumnsIcon/>
|
)}
|
||||||
</ToolBtn>
|
</TableMenuWrapper>
|
||||||
<ToolBtn content={'Remove column'}
|
|
||||||
onClick={() => editor.chain().focus().deleteColumn().run()}
|
|
||||||
>
|
|
||||||
<ContainerIcon/>
|
|
||||||
</ToolBtn>
|
|
||||||
<ToolBtn content={'Remove row'}
|
|
||||||
onClick={() => editor.chain().focus().deleteRow().run()}
|
|
||||||
>
|
|
||||||
<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';
|
||||||
|
}
|
||||||
|
`
|
||||||
Loading…
Add table
Add a link
Reference in a new issue