feat: Table support in article editor (#13974)
This commit is contained in:
@@ -161,8 +161,12 @@ const handleCreateArticle = event => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.editor-root .has-selection {
|
.editor-root .has-selection {
|
||||||
|
.ProseMirror-menubar:not(:has(*)) {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
.ProseMirror-menubar {
|
.ProseMirror-menubar {
|
||||||
@apply h-8 rounded-lg !px-2 z-50 bg-n-solid-3 items-center gap-4 ml-0 mb-0 shadow-md outline outline-1 outline-n-weak;
|
@apply rounded-lg !px-3 !py-1.5 z-50 bg-n-background items-center gap-4 ml-0 mb-0 shadow-md outline outline-1 outline-n-weak;
|
||||||
display: flex;
|
display: flex;
|
||||||
top: var(--selection-top, auto) !important;
|
top: var(--selection-top, auto) !important;
|
||||||
left: var(--selection-left, 0) !important;
|
left: var(--selection-left, 0) !important;
|
||||||
@@ -170,15 +174,10 @@ const handleCreateArticle = event => {
|
|||||||
position: absolute !important;
|
position: absolute !important;
|
||||||
|
|
||||||
.ProseMirror-menuitem {
|
.ProseMirror-menuitem {
|
||||||
@apply mr-0;
|
@apply ltr:mr-0 rtl:ml-0 size-4 flex items-center;
|
||||||
|
|
||||||
.ProseMirror-icon {
|
.ProseMirror-icon {
|
||||||
@apply p-0 mt-0 !mr-0;
|
@apply p-0.5 flex-shrink-0 ltr:mr-2 rtl:ml-2;
|
||||||
|
|
||||||
svg {
|
|
||||||
width: 20px !important;
|
|
||||||
height: 20px !important;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -262,7 +262,8 @@ export default {
|
|||||||
|
|
||||||
// Get the editor's width
|
// Get the editor's width
|
||||||
const editorWidth = editor.offsetWidth;
|
const editorWidth = editor.offsetWidth;
|
||||||
const menubarWidth = 480; // Menubar width (adjust as needed (px))
|
const menubar = editor.querySelector('.ProseMirror-menubar');
|
||||||
|
const menubarWidth = menubar ? menubar.scrollWidth : 480;
|
||||||
|
|
||||||
// Get the end position of the selection
|
// Get the end position of the selection
|
||||||
const { bottom: endBottom, right: endRight } = editorView.coordsAtPos(to);
|
const { bottom: endBottom, right: endRight } = editorView.coordsAtPos(to);
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ export const ARTICLE_EDITOR_MENU_OPTIONS = [
|
|||||||
'h3',
|
'h3',
|
||||||
'imageUpload',
|
'imageUpload',
|
||||||
'code',
|
'code',
|
||||||
|
'insertTable',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<div class="flex max-w-5xl w-full px-4 md:px-8 mx-auto">
|
<div class="flex max-w-5xl w-full px-4 md:px-8 mx-auto">
|
||||||
<article id="cw-article-content" class="article-content flex-grow flex-2 mx-auto text-slate-800 dark:text-slate-50 text-lg max-w-3xl prose-h1:text-2xl prose-h2:text-xl prose-h2:mt-0 prose-h3:text-lg prose-code:[&>p]:p-1 prose-code:[&>p]:rounded-sm prose-code:[&>p]:bg-black-100 dark:prose-code:[&>p]:bg-black-600 prose-code:after:content-none prose-code:before:content-none prose dark:prose-invert break-words w-full <%= @is_plain_layout_enabled ? 'py-4' : 'pt-8 pb-12' %>">
|
<article id="cw-article-content" class="article-content flex-grow flex-2 mx-auto text-slate-800 dark:text-slate-50 text-lg max-w-3xl prose-h1:text-2xl prose-h2:text-xl prose-h2:mt-0 prose-h3:text-lg prose-code:[&>p]:p-1 prose-code:[&>p]:rounded-sm prose-code:[&>p]:bg-black-100 dark:prose-code:[&>p]:bg-black-600 prose-code:after:content-none prose-code:before:content-none prose dark:prose-invert break-words w-full [&_table]:!border-slate-200 dark:[&_table]:!border-slate-800 [&_th]:!border-slate-200 dark:[&_th]:!border-slate-800 [&_td]:!border-slate-200 dark:[&_td]:!border-slate-800 [&_th]:!bg-slate-50 dark:[&_th]:!bg-slate-800/50 <%= @is_plain_layout_enabled ? 'py-4' : 'pt-8 pb-12' %>">
|
||||||
<%= @parsed_content %>
|
<%= @parsed_content %>
|
||||||
</article>
|
</article>
|
||||||
<div class="flex-1" id="cw-hc-toc"></div>
|
<div class="flex-1" id="cw-hc-toc"></div>
|
||||||
@@ -45,4 +45,41 @@
|
|||||||
.article-content li > p {
|
.article-content li > p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
.article-content .tableWrapper {
|
||||||
|
overflow-x: auto;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
.article-content table {
|
||||||
|
min-width: 100%;
|
||||||
|
border: 1px solid;
|
||||||
|
border-radius: 8px;
|
||||||
|
border-spacing: 0;
|
||||||
|
border-collapse: separate;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.article-content th,
|
||||||
|
.article-content td {
|
||||||
|
border-bottom: 1px solid;
|
||||||
|
border-inline-end: 1px solid;
|
||||||
|
border-color: inherit;
|
||||||
|
padding: 0.5rem 0.75rem;
|
||||||
|
text-align: start;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
.article-content th:last-child,
|
||||||
|
.article-content td:last-child {
|
||||||
|
border-inline-end: none;
|
||||||
|
}
|
||||||
|
.article-content th {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.article-content th:first-child {
|
||||||
|
border-start-start-radius: 7px;
|
||||||
|
}
|
||||||
|
.article-content th:last-child {
|
||||||
|
border-start-end-radius: 7px;
|
||||||
|
}
|
||||||
|
.article-content tr:last-child td {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -9,6 +9,12 @@ class CustomMarkdownRenderer < CommonMarker::HtmlRenderer
|
|||||||
@embed_regexes ||= config.transform_values { |embed_config| Regexp.new(embed_config['regex']) }
|
@embed_regexes ||= config.transform_values { |embed_config| Regexp.new(embed_config['regex']) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def table(node)
|
||||||
|
out('<div class="tableWrapper">')
|
||||||
|
super
|
||||||
|
out('</div>')
|
||||||
|
end
|
||||||
|
|
||||||
def text(node)
|
def text(node)
|
||||||
content = node.string_content
|
content = node.string_content
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
"@amplitude/analytics-browser": "^2.11.10",
|
"@amplitude/analytics-browser": "^2.11.10",
|
||||||
"@breezystack/lamejs": "^1.2.7",
|
"@breezystack/lamejs": "^1.2.7",
|
||||||
"@chatwoot/ninja-keys": "1.2.3",
|
"@chatwoot/ninja-keys": "1.2.3",
|
||||||
"@chatwoot/prosemirror-schema": "1.3.9",
|
"@chatwoot/prosemirror-schema": "1.3.10",
|
||||||
"@chatwoot/utils": "^0.0.52",
|
"@chatwoot/utils": "^0.0.52",
|
||||||
"@formkit/core": "^1.7.2",
|
"@formkit/core": "^1.7.2",
|
||||||
"@formkit/vue": "^1.7.2",
|
"@formkit/vue": "^1.7.2",
|
||||||
|
|||||||
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@@ -26,8 +26,8 @@ importers:
|
|||||||
specifier: 1.2.3
|
specifier: 1.2.3
|
||||||
version: 1.2.3
|
version: 1.2.3
|
||||||
'@chatwoot/prosemirror-schema':
|
'@chatwoot/prosemirror-schema':
|
||||||
specifier: 1.3.9
|
specifier: 1.3.10
|
||||||
version: 1.3.9
|
version: 1.3.10
|
||||||
'@chatwoot/utils':
|
'@chatwoot/utils':
|
||||||
specifier: ^0.0.52
|
specifier: ^0.0.52
|
||||||
version: 0.0.52
|
version: 0.0.52
|
||||||
@@ -454,8 +454,8 @@ packages:
|
|||||||
'@chatwoot/ninja-keys@1.2.3':
|
'@chatwoot/ninja-keys@1.2.3':
|
||||||
resolution: {integrity: sha512-xM8d9P5ikDMZm2WbaCTk/TW5HFauylrU3cJ75fq5je6ixKwyhl/0kZbVN/vbbZN4+AUX/OaSIn6IJbtCgIF67g==}
|
resolution: {integrity: sha512-xM8d9P5ikDMZm2WbaCTk/TW5HFauylrU3cJ75fq5je6ixKwyhl/0kZbVN/vbbZN4+AUX/OaSIn6IJbtCgIF67g==}
|
||||||
|
|
||||||
'@chatwoot/prosemirror-schema@1.3.9':
|
'@chatwoot/prosemirror-schema@1.3.10':
|
||||||
resolution: {integrity: sha512-nbzvW4Rfe7EC+tHF/wWJK5pIxRzfQj/DDAtZI7pwM9uJfv9yQz6bAUCA7kz7Vq1NF29XOisZaT5W0005ygk1pg==}
|
resolution: {integrity: sha512-MtOXqFPHptFHu/AoIPhQ9TskVXOxOXCgBY/tgAtCAQRut978F7I3QxozQBECBz83ubsoXnBecpNjGNq0OPgONw==}
|
||||||
|
|
||||||
'@chatwoot/utils@0.0.52':
|
'@chatwoot/utils@0.0.52':
|
||||||
resolution: {integrity: sha512-e57uVqyVW4tj1gql4YJPNMykqMJPkETn5Y9AmHdhc6Y7oxDXfRXBq27fZrrDadLkZdn5RYVCZjfIhXOumyYv2Q==}
|
resolution: {integrity: sha512-e57uVqyVW4tj1gql4YJPNMykqMJPkETn5Y9AmHdhc6Y7oxDXfRXBq27fZrrDadLkZdn5RYVCZjfIhXOumyYv2Q==}
|
||||||
@@ -4967,7 +4967,7 @@ snapshots:
|
|||||||
hotkeys-js: 3.8.7
|
hotkeys-js: 3.8.7
|
||||||
lit: 2.2.6
|
lit: 2.2.6
|
||||||
|
|
||||||
'@chatwoot/prosemirror-schema@1.3.9':
|
'@chatwoot/prosemirror-schema@1.3.10':
|
||||||
dependencies:
|
dependencies:
|
||||||
markdown-it-sup: 2.0.0
|
markdown-it-sup: 2.0.0
|
||||||
prosemirror-commands: 1.6.0
|
prosemirror-commands: 1.6.0
|
||||||
|
|||||||
Reference in New Issue
Block a user