Text & Table cell color styling features (#7624)

Signed-off-by: Victor Ilyushchenko <alt13ri@gmail.com>
This commit is contained in:
Victor Ilyushchenko
2025-01-10 16:32:30 +07:00
committed by GitHub
parent f5c3c5720a
commit 24b66777ea
21 changed files with 469 additions and 22 deletions
+11 -1
View File
@@ -6254,6 +6254,14 @@ packages:
'@tiptap/core': 2.6.6(@tiptap/pm@2.6.6)
dev: false
/@tiptap/extension-text-style@2.11.0(@tiptap/core@2.6.6):
resolution: {integrity: sha512-vuA16wMZ6J3fboL7FObwV2f5uN9Vg0WYmqU7971vxzJyaRj9VE1eeH8Kh5fq4RgwDzc13MZGvZZV4HcE1R8o8A==}
peerDependencies:
'@tiptap/core': ^2.7.0
dependencies:
'@tiptap/core': 2.6.6(@tiptap/pm@2.6.6)
dev: false
/@tiptap/extension-text@2.6.6(@tiptap/core@2.6.6):
resolution: {integrity: sha512-e84uILnRzNzcwK1DVQNpXVmBG1Cq3BJipTOIDl1LHifOok7MBjhI/X+/NR0bd3N2t6gmDTWi63+4GuJ5EeDmsg==}
peerDependencies:
@@ -32495,6 +32503,7 @@ packages:
'@tiptap/extension-table-header': 2.6.6(@tiptap/core@2.6.6)
'@tiptap/extension-table-row': 2.6.6(@tiptap/core@2.6.6)
'@tiptap/extension-text-align': 2.11.0(@tiptap/core@2.6.6)
'@tiptap/extension-text-style': 2.11.0(@tiptap/core@2.6.6)
'@tiptap/extension-typography': 2.6.6(@tiptap/core@2.6.6)
'@tiptap/extension-underline': 2.6.6(@tiptap/core@2.6.6)
'@tiptap/pm': 2.6.6
@@ -32639,7 +32648,7 @@ packages:
dev: false
file:projects/text.tgz(@types/node@20.11.19)(bufferutil@4.0.8)(esbuild@0.24.2)(ts-node@10.9.2)(utf-8-validate@6.0.4):
resolution: {integrity: sha512-zmM6GDzeNuMbMA7iWwhg8hBc43fylNW7cEmk0fSWw9+G9NqD2MLv2dVb5dnAcPAioj9WBdDakWcrLAAHUBJyMw==, tarball: file:projects/text.tgz}
resolution: {integrity: sha512-p2TRL6FgtqVBooDf+E5A4HB+45VS03IvNxudhC9gCotewS726ZLOxl2XdfeuYB2rHYbzdmmiG2zb8GbPwqTkOw==, tarball: file:projects/text.tgz}
id: file:projects/text.tgz
name: '@rush-temp/text'
version: 0.0.0
@@ -32660,6 +32669,7 @@ packages:
'@tiptap/extension-task-item': 2.6.6(@tiptap/core@2.6.6)(@tiptap/pm@2.6.6)
'@tiptap/extension-task-list': 2.6.6(@tiptap/core@2.6.6)
'@tiptap/extension-text-align': 2.11.0(@tiptap/core@2.6.6)
'@tiptap/extension-text-style': 2.11.0(@tiptap/core@2.6.6)
'@tiptap/extension-typography': 2.6.6(@tiptap/core@2.6.6)
'@tiptap/extension-underline': 2.6.6(@tiptap/core@2.6.6)
'@tiptap/html': 2.6.6(@tiptap/core@2.6.6)(@tiptap/pm@2.6.6)
+27 -2
View File
@@ -247,6 +247,18 @@ export function createModel (builder: Builder): void {
index: 20
})
builder.createDoc(textEditor.class.TextEditorAction, core.space.Model, {
action: textEditor.function.SetTextColor,
icon: textEditor.icon.TextStyle,
visibilityTester: textEditor.function.IsTextStylingEnabled,
isActive: {
name: 'textStyle'
},
label: textEditor.string.SetTextColor,
category: 20,
index: 25
})
// Link category
builder.createDoc(textEditor.class.TextEditorAction, core.space.Model, {
action: textEditor.function.FormatLink,
@@ -338,23 +350,36 @@ export function createModel (builder: Builder): void {
index: 10
})
// Table cell category
builder.createDoc(textEditor.class.TextEditorAction, core.space.Model, {
kind: 'table',
action: textEditor.function.SetBackgroundColor,
icon: textEditor.icon.Brush,
visibilityTester: textEditor.function.IsTableToolbarContext,
label: textEditor.string.SetCellHighlightColor,
category: 65,
index: 5
})
// Table category
builder.createDoc(textEditor.class.TextEditorAction, core.space.Model, {
kind: 'table',
action: textEditor.function.SelectTable,
icon: textEditor.icon.SelectTable,
visibilityTester: textEditor.function.IsTableToolbarContext,
label: textEditor.string.SelectTable,
category: 70,
index: 5
index: 15
})
builder.createDoc(textEditor.class.TextEditorAction, core.space.Model, {
kind: 'table',
action: textEditor.function.OpenTableOptions,
icon: textEditor.icon.TableProps,
visibilityTester: textEditor.function.IsTableToolbarContext,
label: textEditor.string.TableOptions,
category: 70,
index: 10
index: 20
})
// Image align category
+5 -1
View File
@@ -36,9 +36,13 @@ export default mergeIds(textEditorId, textEditor, {
IsTableToolbarContext: '' as Resource<TextActionVisibleFunction>,
IsEditableNote: '' as Resource<TextActionVisibleFunction>,
IsEditable: '' as Resource<TextActionVisibleFunction>,
IsTextStylingEnabled: '' as Resource<TextActionVisibleFunction>,
IsHeadingVisible: '' as Resource<TextActionVisibleFunction>,
CreateInlineComment: '' as Resource<TextActionFunction>,
ShouldShowCreateInlineCommentAction: '' as Resource<TextActionVisibleFunction>
ShouldShowCreateInlineCommentAction: '' as Resource<TextActionVisibleFunction>,
SetBackgroundColor: '' as Resource<TextActionFunction>,
SetTextColor: '' as Resource<TextActionFunction>
}
})
+2 -1
View File
@@ -64,7 +64,8 @@
"prosemirror-codemark": "^0.4.2",
"markdown-it": "^14.0.0",
"fast-equals": "^5.0.1",
"@tiptap/extension-text-align": "~2.11.0"
"@tiptap/extension-text-align": "~2.11.0",
"@tiptap/extension-text-style": "~2.11.0"
},
"repository": "https://github.com/hcengineering/platform",
"publishConfig": {
+3
View File
@@ -22,6 +22,7 @@ export * from './markup/utils'
export * from './nodes'
// export * from './ydoc'
export * from './marks/code'
export * from './marks/colors'
export * from './marks/noteBase'
export * from './markdown'
export * from './markdown/serializer'
@@ -31,3 +32,5 @@ export * from './markdown/node'
export * from './kits/default-kit'
export * from './kits/server-kit'
export { TextStyle, type TextStyleOptions } from '@tiptap/extension-text-style'
+6 -1
View File
@@ -34,6 +34,8 @@ import { CodeExtension, codeOptions } from '../marks/code'
import { NoteBaseExtension } from '../marks/noteBase'
import { CommentNode } from '../nodes/comment'
import TextAlign from '@tiptap/extension-text-align'
import TextStyle from '@tiptap/extension-text-style'
import { BackgroundColor, TextColor } from '../marks/colors'
const headingLevels: Level[] = [1, 2, 3, 4, 5, 6]
@@ -97,7 +99,10 @@ export const ServerKit = Extension.create<ServerKitOptions>({
ReferenceNode,
CommentNode,
NodeUuid,
NoteBaseExtension
NoteBaseExtension,
TextStyle.configure({}),
TextColor.configure({}),
BackgroundColor.configure({ types: ['tableCell'] })
]
}
})
+142
View File
@@ -0,0 +1,142 @@
//
// Copyright © 2025 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
import { Extension } from '@tiptap/core'
import '@tiptap/extension-text-style'
export interface BackgroundColorOptions {
types: string[]
}
declare module '@tiptap/core' {
interface Commands<ReturnType> {
colors: {
setTextColor: (color: string) => ReturnType
unsetTextColor: () => ReturnType
setBackgroundColor: (color: string) => ReturnType
unsetBackgroundColor: () => ReturnType
}
}
}
export const BackgroundColor = Extension.create<BackgroundColorOptions>({
name: 'backgroundColor',
addOptions () {
return {
types: []
}
},
addGlobalAttributes () {
return [
{
types: this.options.types,
attributes: {
backgroundColor: {
parseHTML: (element) => {
return element.getAttribute('data-background-color') ?? undefined
},
renderHTML: (attributes) => {
if (typeof attributes.backgroundColor !== 'string') {
return {}
}
return {
'data-background-color': attributes.backgroundColor,
style: `background-color: ${attributes.backgroundColor}`
}
}
}
}
}
]
},
addCommands () {
return {
setBackgroundColor:
(backgroundColor: string) =>
({ commands }) => {
return this.options.types
.map((type) => commands.updateAttributes(type, { backgroundColor }))
.every((response) => response)
},
unsetBackgroundColor:
() =>
({ commands }) => {
return this.options.types
.map((type) => commands.resetAttributes(type, 'backgroundColor'))
.every((response) => response)
}
}
}
})
export interface TextColorOptions {
types: string[]
}
export const TextColor = Extension.create<TextColorOptions>({
name: 'textColor',
addOptions () {
return {
types: ['textStyle']
}
},
addGlobalAttributes () {
return [
{
types: this.options.types,
attributes: {
color: {
parseHTML: (element) => {
return element.getAttribute('data-color') ?? undefined
},
renderHTML: (attributes) => {
if (typeof attributes.color !== 'string') {
return {}
}
return {
'data-color': attributes.color,
style: `color: ${attributes.color}`
}
}
}
}
}
]
},
addCommands () {
return {
setTextColor:
(color: string) =>
({ chain }) => {
return chain().setMark('textStyle', { color }).run()
},
unsetTextColor:
() =>
({ chain }) => {
return chain().setMark('textStyle', { color: null }).removeEmptyTextStyle().run()
}
}
}
})
+44
View File
@@ -248,6 +248,28 @@
--theme-text-editor-note-anchor-bg-primary: #688797;
--theme-text-editor-note-anchor-bg-primary-light: #747C81;
--text-editor-table-border-color: hsl(220, 6%, 40%);
--theme-text-editor-palette-text-gray: rgba(155, 155, 155, 1);
--theme-text-editor-palette-text-brown: rgba(186, 133, 111, 1);
--theme-text-editor-palette-text-orange: rgba(199, 125, 72, 1);
--theme-text-editor-palette-text-yellow: rgba(202, 152, 73, 1);
--theme-text-editor-palette-text-green: rgba(82, 158, 114, 1);
--theme-text-editor-palette-text-blue: rgba(94, 135, 201, 1);
--theme-text-editor-palette-text-purple: rgba(157, 104, 211, 1);
--theme-text-editor-palette-text-pink: rgba(209, 87, 150, 1);
--theme-text-editor-palette-text-red: rgba(223, 84, 82, 1);
--theme-text-editor-palette-bg-gray: rgba(47, 47, 47, 1);
--theme-text-editor-palette-bg-brown: rgba(74, 50, 40, 1);
--theme-text-editor-palette-bg-orange: rgba(92, 59, 35, 1);
--theme-text-editor-palette-bg-yellow: rgba(86, 67, 40, 1);
--theme-text-editor-palette-bg-green: rgba(36, 61, 48, 1);
--theme-text-editor-palette-bg-blue: rgba(20, 58, 78, 1);
--theme-text-editor-palette-bg-purple: rgba(60, 45, 73, 1);
--theme-text-editor-palette-bg-pink: rgba(78, 44, 60, 1);
--theme-text-editor-palette-bg-red:rgba(82, 46, 42, 1);
--accent-bg-color: #27282b;
--accent-shadow: rgb(0 0 0 / 10%) 0px 2px 4px;
@@ -507,6 +529,28 @@
--theme-text-editor-note-anchor-bg-primary: #AAC5E9;
--theme-text-editor-note-anchor-bg-primary-light: #D5E5F5;
--text-editor-table-border-color: #c9cbcd;
--theme-text-editor-palette-text-gray: rgba(120, 119, 116, 1);
--theme-text-editor-palette-text-brown: rgba(159, 107, 83, 1);
--theme-text-editor-palette-text-orange: rgba(217, 115, 13, 1);
--theme-text-editor-palette-text-yellow: rgba(203, 145, 47, 1);
--theme-text-editor-palette-text-green: rgba(68, 131, 97, 1);
--theme-text-editor-palette-text-blue: rgba(51, 126, 169, 1);
--theme-text-editor-palette-text-purple: rgba(144, 101, 176, 1);
--theme-text-editor-palette-text-pink: rgba(193, 76, 138, 1);
--theme-text-editor-palette-text-red: rgba(212, 76, 71, 1);
--theme-text-editor-palette-bg-gray: rgba(241, 241, 239, 1);
--theme-text-editor-palette-bg-brown: rgba(244, 238, 238, 1);
--theme-text-editor-palette-bg-orange: rgba(251, 236, 221, 1);
--theme-text-editor-palette-bg-yellow: rgba(251, 243, 219, 1);
--theme-text-editor-palette-bg-green: rgba(237, 243, 236, 1);
--theme-text-editor-palette-bg-blue: rgba(231, 243, 248, 1);
--theme-text-editor-palette-bg-purple: rgba(244, 240, 247, 0.8);
--theme-text-editor-palette-bg-pink: rgba(249, 238, 243, 0.8);
--theme-text-editor-palette-bg-red: rgba(253, 235, 236, 1);
--accent-bg-color: #eff0f2; // HZ
--accent-shadow: rgb(0 0 0 / 10%) 0px 2px 4px; // Dark
+1 -1
View File
@@ -38,7 +38,7 @@ table.proseTable {
th {
min-width: 1rem;
height: 2rem;
border: 1px solid var(--button-border-hover);
border: 1px solid var(--text-editor-table-border-color);
padding: .25rem .5rem;
vertical-align: top;
box-sizing: border-box;
@@ -214,4 +214,11 @@
<path d="M3 6C3 4.34315 4.34315 3 6 3H17C18.6569 3 20 4.34315 20 6V10.5556V17C20 18.6569 18.6569 20 17 20H10.5556H6C4.34314 20 3 18.6569 3 17V6Z" stroke="currentColor" stroke-width="2"/>
<path d="M12 15C12 13.3431 13.3431 12 15 12H26C27.6569 12 29 13.3431 29 15V26C29 27.6569 27.6569 29 26 29H15C13.3431 29 12 27.6569 12 26V15Z" stroke="currentColor" stroke-width="2"/>
</symbol>
<symbol id="brush" viewBox="0 0 14 14" fill="none">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.9142 1.08579L13.4142 2.58579C14.1952 3.36683 14.1952 4.63316 13.4142 5.41421L6.91416 11.9142C6.52365 12.3047 6.01183 12.5 5.5 12.5H4L2.5 13.5L0.5 12.5L2 10.5V9C2 8.48816 2.19526 7.97631 2.58579 7.58579L9.08579 1.08579C9.86684 0.304738 11.1332 0.304738 11.9142 1.08579ZM6.20705 11.2071C6.01161 11.4025 5.75745 11.5 5.5 11.5H4H3V9C3 8.74253 3.09744 8.48835 3.29289 8.29289L4.43936 7.14643L7.35354 10.0606L6.20705 11.2071ZM8.06065 9.35351L5.14646 6.43932L9.79289 1.79289C10.1834 1.40237 10.8166 1.40238 11.2071 1.79289L12.707 3.29289C13.0976 3.68342 13.0976 4.31658 12.707 4.70711L8.06065 9.35351Z" fill="currentColor"/>
</symbol>
<symbol id="textStyle" viewBox="0 0 16 16" fill="none">
<path d="M13 12H3V14H13V12Z" fill="currentColor"/>
<path d="M11 10.5H12L8.69037 2.46234C8.57518 2.18258 8.30254 2 8 2C7.69746 2 7.42482 2.18258 7.30963 2.46234L4 10.5H5L5.805 8.5H10.175L11 10.5ZM6.215 7.5L7.935 3.315H8.065L9.77 7.5H6.215Z" fill="currentColor"/>
</symbol>
</svg>

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 24 KiB

+3 -1
View File
@@ -66,6 +66,8 @@
"MermaidDiargram": "Diagram",
"Comment": "Comment",
"AddComment": "Add a comment",
"AddCommentPlaceholder": "Add a comment..."
"AddCommentPlaceholder": "Add a comment...",
"SetCellHighlightColor": "Set cell color",
"SetTextColor": "Set text color"
}
}
+3 -1
View File
@@ -66,6 +66,8 @@
"MermaidDiargram": "Диаграмма",
"Comment": "Комментарий",
"AddComment": "Добавить комментарий",
"AddCommentPlaceholder": "Добавьте комментарий..."
"AddCommentPlaceholder": "Добавьте комментарий...",
"SetCellHighlightColor": "Изменить цвет ячеек",
"SetTextColor": "Изменить цвет текста"
}
}
+3 -1
View File
@@ -43,5 +43,7 @@ loadMetadata(textEditor.icon, {
Comment: `${icons}#comment`,
SelectTable: `${icons}#move`,
MergeCells: `${icons}#union`,
SplitCells: `${icons}#divide`
SplitCells: `${icons}#divide`,
Brush: `${icons}#brush`,
TextStyle: `${icons}#textStyle`
})
@@ -0,0 +1,100 @@
//
// Copyright © 2025 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
import { getEventPositionElement, showPopup } from '@hcengineering/ui'
import { type Editor } from '@tiptap/core'
import ColorPicker from './popups/ColorPicker.svelte'
import { type ActionContext } from '@hcengineering/text-editor'
export interface BackgroundColorOptions {
types: string[]
}
interface ColorSpec {
color: string
preview?: string
}
function colorVar (tag: string, prefix = 'text'): string {
return `var(--theme-text-editor-palette-${prefix}-${tag})`
}
function colorSpec (tag: string, prefix = 'text'): ColorSpec {
const color = colorVar(tag, prefix)
return { color, preview: colorVar(tag) }
}
const palette = {
background: [
{ color: 'transparent' },
colorSpec('gray', 'bg'),
colorSpec('brown', 'bg'),
colorSpec('orange', 'bg'),
colorSpec('yellow', 'bg'),
colorSpec('green', 'bg'),
colorSpec('blue', 'bg'),
colorSpec('purple', 'bg'),
colorSpec('pink', 'bg'),
colorSpec('red', 'bg')
],
text: [
{ color: 'var(--theme-text-color-primary)' },
colorSpec('gray'),
colorSpec('brown'),
colorSpec('orange'),
colorSpec('yellow'),
colorSpec('green'),
colorSpec('blue'),
colorSpec('purple'),
colorSpec('pink'),
colorSpec('red')
]
}
export async function openBackgroundColorOptions (editor: Editor, event: MouseEvent): Promise<void> {
await new Promise<void>((resolve) => {
showPopup(ColorPicker, { palette: palette.background }, getEventPositionElement(event), (val) => {
const color: string | undefined = val?.color
if (color === undefined) return
if (color === 'transparent') {
editor.commands.unsetBackgroundColor()
} else {
editor.commands.setBackgroundColor(color)
}
resolve()
})
})
}
export async function openTextColorOptions (editor: Editor, event: MouseEvent): Promise<void> {
await new Promise<void>((resolve) => {
showPopup(ColorPicker, { palette: palette.text }, getEventPositionElement(event), (val) => {
const color: string | undefined = val?.color
if (color === undefined) return
if (color === 'var(--theme-text-color-primary)') {
editor.commands.unsetTextColor()
} else {
editor.commands.setTextColor(color)
}
resolve()
})
})
}
export async function isTextStylingEnabled (editor: Editor, context: ActionContext): Promise<boolean> {
return editor.isEditable && editor.commands.setTextColor !== undefined
}
@@ -0,0 +1,65 @@
<!--
// Copyright © 2025 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import { Card } from '@hcengineering/presentation'
export let palette: Array<{ color: string, preview?: string }> = [{ color: 'transparent' }]
const dispatch = createEventDispatcher()
function handleSubmit (color: { color: string }): void {
dispatch('close', color)
}
</script>
<div class="picker">
<div class="palette">
{#each palette as k}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
class="colorBox"
style:background-color={k.preview ?? k.color}
on:click={() => {
handleSubmit(k)
}}
/>
{/each}
</div>
</div>
<style lang="scss">
.picker {
background: var(--theme-popup-color);
border-radius: 0.5rem;
box-shadow: var(--theme-popup-shadow);
padding: 0.5rem;
margin-left: -4rem;
}
.palette {
display: flex;
gap: 0.25rem;
}
.colorBox {
position: relative;
width: 1.5rem;
height: 1.5rem;
border: 1px solid var(--theme-button-border);
cursor: pointer;
}
</style>
@@ -200,7 +200,7 @@
.table-toolbar-container {
position: absolute;
top: -1.5rem;
right: 0;
right: var(--table-offscreen-spacing);
z-index: 200;
}
</style>
@@ -50,15 +50,34 @@
actions = out
}
$: actionsQuery.query(textEditor.class.TextEditorAction, { category: 70 }, (result) => {
$: actionsQuery.query(textEditor.class.TextEditorAction, { kind: 'table' }, (result) => {
void updateActions([...result], actionCtx)
})
$: categories = actions.reduce<[number, TextEditorAction][][]>((acc, action) => {
const { category, index } = action
if (acc[category] === undefined) acc[category] = []
acc[category].push([index, action])
return acc
}, [])
$: categories.forEach((category) => {
category.sort((a, b) => a[0] - b[0])
})
</script>
<div class="table-toolbar flex" contenteditable="false">
{#each actions as action}
<TextActionButton {action} {editor} size="small" {actionCtx} blockMouseEvents={false} />
{/each}
<div class="text-editor-toolbar buttons-group xsmall-gap">
{#each Object.values(categories) as category, index}
{#if index > 0}
<div class="buttons-divider" />
{/if}
{#each category as [_, action]}
<TextActionButton {action} {editor} size="small" {actionCtx} blockMouseEvents={false} />
{/each}
{/each}
</div>
</div>
<style lang="scss">
+6 -1
View File
@@ -26,6 +26,7 @@ import {
import { openImage, downloadImage, expandImage, moreImageActions } from './components/extension/imageExt'
import { configureNote, isEditableNote } from './components/extension/note'
import { createInlineComment, shouldShowCreateInlineCommentAction } from './components/extension/inlineComment'
import { isTextStylingEnabled, openBackgroundColorOptions, openTextColorOptions } from './components/extension/colors'
export * from '@hcengineering/presentation/src/types'
export type { EditorKitOptions } from './kits/editor-kit'
@@ -97,8 +98,12 @@ export default async (): Promise<Resources> => ({
IsEditableNote: isEditableNote,
IsEditable: isEditable,
IsHeadingVisible: isHeadingVisible,
IsTextStylingEnabled: isTextStylingEnabled,
CreateInlineComment: createInlineComment,
ShouldShowCreateInlineCommentAction: shouldShowCreateInlineCommentAction
ShouldShowCreateInlineCommentAction: shouldShowCreateInlineCommentAction,
SetBackgroundColor: openBackgroundColorOptions,
SetTextColor: openTextColorOptions
}
})
@@ -15,7 +15,7 @@
import { type Class, type Doc, type Ref, type Space } from '@hcengineering/core'
import { getResource } from '@hcengineering/platform'
import { getBlobRef, getClient } from '@hcengineering/presentation'
import { CodeExtension, codeOptions } from '@hcengineering/text'
import { BackgroundColor, CodeExtension, codeOptions, TextColor, TextStyle } from '@hcengineering/text'
import textEditor, { type ActionContext, type ExtensionCreator, type TextEditorMode } from '@hcengineering/text-editor'
import { type AnyExtension, type Editor, Extension } from '@tiptap/core'
import { type Level } from '@tiptap/extension-heading'
@@ -201,6 +201,12 @@ async function buildEditorKit (): Promise<Extension<EditorKitOptions, any>> {
staticKitExtensions.push([400, ParagraphExtension.configure()])
}
if (mode === 'full') {
staticKitExtensions.push([410, TextStyle.configure({})])
staticKitExtensions.push([420, TextColor.configure({})])
staticKitExtensions.push([430, BackgroundColor.configure({ types: ['tableCell'] })])
}
staticKitExtensions.push([
500,
ListKeymapExtension.configure({
+9 -4
View File
@@ -93,8 +93,6 @@ export default plugin(textEditorId, {
CategoryColumn: '' as IntlString,
CategoryCell: '' as IntlString,
Table: '' as IntlString,
TableOptions: '' as IntlString,
SelectTable: '' as IntlString,
Width: '' as IntlString,
Height: '' as IntlString,
Unset: '' as IntlString,
@@ -102,7 +100,12 @@ export default plugin(textEditorId, {
SeparatorLine: '' as IntlString,
TodoList: '' as IntlString,
DrawingBoard: '' as IntlString,
MermaidDiargram: '' as IntlString
MermaidDiargram: '' as IntlString,
TableOptions: '' as IntlString,
SelectTable: '' as IntlString,
SetCellHighlightColor: '' as IntlString,
SetTextColor: '' as IntlString
},
icon: {
Header1: '' as Asset,
@@ -130,6 +133,8 @@ export default plugin(textEditorId, {
Comment: '' as Asset,
SelectTable: '' as Asset,
MergeCells: '' as Asset,
SplitCells: '' as Asset
SplitCells: '' as Asset,
Brush: '' as Asset,
TextStyle: '' as Asset
}
})
+1 -1
View File
@@ -186,7 +186,7 @@ export interface ActiveDescriptor {
params?: any
}
export type TextEditorActionKind = 'text' | 'image'
export type TextEditorActionKind = 'text' | 'image' | 'table'
/**
* Defines a text action for text action editor