Skip to content

Commit

Permalink
#21991 Add table block (#23418)
Browse files Browse the repository at this point in the history
* table block

* clean up

* feedback

* cell background correction
  • Loading branch information
hmoreras committed Dec 1, 2022
1 parent 3532c80 commit 902c5a1
Show file tree
Hide file tree
Showing 28 changed files with 769 additions and 101 deletions.
Expand Up @@ -34,7 +34,7 @@ <h2 class="flex align-items-center gap-1 uppercase">

<p-button
data-testId="variant-weight"
label="{{ variant.weight | number : '2.2-2' }}% {{
label="{{ variant.weight | number: '2.2-2' }}% {{
'experiments.configure.variants.weight' | dm
}}"
styleClass="p-button-sm p-button-link"
Expand Down
Expand Up @@ -18,7 +18,7 @@

.editor-wrapper {
display: block;
border-radius: 4px;
border-radius: $border-radius-md;
height: 500px;
overflow: hidden;
position: relative;
Expand Down Expand Up @@ -139,6 +139,98 @@
height: 0;
pointer-events: none;
}

table {
border-collapse: collapse;
margin: 0;
overflow: hidden;
table-layout: fixed;
width: 100%;

td,
th {
border: 2px solid $gray-light;
box-sizing: border-box;
min-width: $spacing-3;
padding: 3px 20px 3px 5px;
position: relative;
vertical-align: top;
}

td > *,
th > * {
margin-bottom: 0;
}

th {
background-color: $gray-bg;
font-weight: 700;
text-align: left;
}

.selectedCell {
background-color: $gray-lighter;
}

.selectedCell:after {
content: "";
left: 0;
right: 0;
top: 0;
bottom: 0;
pointer-events: none;
position: absolute;
}

.column-resize-handle {
bottom: -2px;
position: absolute;
right: -2px;
pointer-events: none;
top: 0;
width: 4px;
}

p {
margin: 0;
}

.tableWrapper {
padding: $spacing-3 0;
overflow-x: auto;
}

.resize-cursor {
cursor: ew-resize;
cursor: col-resize;
}

.dot-cell-arrow {
position: absolute;
display: none;
top: 3px;
right: 5px;
border: solid black;
border-width: 0 2px 2px 0;
padding: 3px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
background: transparent;
cursor: pointer;
z-index: 100;
}
.selectedCell {
.dot-cell-arrow {
display: block;
}
}
td.focus,
th.focus {
.dot-cell-arrow {
display: block;
}
}
}
}
}
}
Expand Up @@ -21,7 +21,10 @@ import {
DotFloatingButton,
ImageNode,
SetDocAttrStep,
formatHTML
formatHTML,
DotTableCellExtension,
DotTableExtension,
DotTableHeaderExtension
} from '@dotcms/block-editor';

// Marks Extensions
Expand All @@ -30,6 +33,7 @@ import { Link } from '@tiptap/extension-link';
import { TextAlign } from '@tiptap/extension-text-align';
import { Underline } from '@tiptap/extension-underline';
import CharacterCount, { CharacterCountStorage } from '@tiptap/extension-character-count';
import { TableRow } from '@tiptap/extension-table-row';

function toTitleCase(str) {
return str.replace(/\p{L}+('\p{L}+)?/gu, function (txt) {
Expand Down Expand Up @@ -141,7 +145,11 @@ export class DotBlockEditorComponent implements OnInit, OnDestroy {

return 'Type "/" for commmands';
}
})
}),
DotTableCellExtension(this.viewContainerRef),
DotTableHeaderExtension(),
TableRow,
DotTableExtension()
];
const customExtensions: Map<string, AnyExtension> = new Map([
['contentlets', ContentletBlock(this.injector)],
Expand Down
@@ -1,6 +1,6 @@
import { ComponentRef, ViewContainerRef } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { take, takeUntil } from 'rxjs/operators';

import { PluginKey } from 'prosemirror-state';
import { Editor, Extension, Range } from '@tiptap/core';
Expand All @@ -21,7 +21,9 @@ import {
SuggestionsComponent,
CONTENT_SUGGESTION_ID,
suggestionOptions,
SuggestionPopperModifiers
SuggestionPopperModifiers,
findParentNode,
NodeTypes
} from '@dotcms/block-editor';

import { ActionButtonComponent } from './action-button.component';
Expand Down Expand Up @@ -101,6 +103,54 @@ function execCommand({
heading: () => {
editor.chain().addHeading({ range, type: props.type }).run();
},
table: () => {
editor.commands
.openForm(
[
{
key: 'rows',
label: 'Rows',
required: true,
value: '3',
controlType: 'number',
type: 'number',
min: 1
},
{
key: 'columns',
label: 'Columns',
required: true,
value: '3',
controlType: 'number',
type: 'number',
min: 1
},
{
key: 'header',
label: 'Add Row Header',
required: false,
value: true,
controlType: 'text',
type: 'checkbox'
}
],
{ customClass: 'dotTableForm' }
)
.pipe(take(1))
.subscribe((value) => {
requestAnimationFrame(() => {
editor
.chain()
.insertTable({
rows: value.rows,
cols: value.columns,
withHeaderRow: !!value.header
})
.focus()
.run();
});
});
},
orderedList: () => {
editor.chain().deleteRange(range).toggleOrderedList().focus().run();
},
Expand Down Expand Up @@ -128,25 +178,36 @@ export const ActionsMenu = (viewContainerRef: ViewContainerRef) => {
let suggestionsComponent: ComponentRef<SuggestionsComponent>;
const suggestionKey = new PluginKey('suggestionPlugin');
const destroy$: Subject<boolean> = new Subject<boolean>();
let shouldShow = true;

/**
* Get's called on button click or suggestion char
*
* @param {(SuggestionProps | FloatingActionsProps)} { editor, range, clientRect }
*/
function onStart({ editor, range, clientRect }: SuggestionProps | FloatingActionsProps): void {
setUpSuggestionComponent(editor, range);
myTippy = getTippyInstance({
element: editor.options.element.parentElement,
content: suggestionsComponent.location.nativeElement,
rect: clientRect,
onHide: () => {
const transaction = editor.state.tr.setMeta(FLOATING_ACTIONS_MENU_KEYBOARD, {
open: false
});
editor.view.dispatch(transaction);
}
});
if (shouldShow) {
setUpSuggestionComponent(editor, range);
myTippy = getTippyInstance({
element: editor.options.element.parentElement,
content: suggestionsComponent.location.nativeElement,
rect: clientRect,
onHide: () => {
const transaction = editor.state.tr.setMeta(FLOATING_ACTIONS_MENU_KEYBOARD, {
open: false
});
editor.view.dispatch(transaction);
}
});
}
}

function onBeforeStart({ editor }): void {
const isTableCell =
findParentNode(editor.view.state.selection.$from, [NodeTypes.TABLE_CELL])?.type.name ===
NodeTypes.TABLE_CELL;

shouldShow = !isTableCell;
}

function setUpSuggestionComponent(editor: Editor, range: Range) {
Expand Down Expand Up @@ -214,7 +275,7 @@ export const ActionsMenu = (viewContainerRef: ViewContainerRef) => {

function onExit() {
myTippy?.destroy();
suggestionsComponent.destroy();
suggestionsComponent?.destroy();
suggestionsComponent = null;
destroy$.next(true);
destroy$.complete();
Expand All @@ -234,6 +295,7 @@ export const ActionsMenu = (viewContainerRef: ViewContainerRef) => {
startOfLine: true,
render: () => {
return {
onBeforeStart,
onStart,
onKeyDown,
onExit
Expand Down
@@ -1,16 +1,28 @@
<form *ngIf="form" [formGroup]="form" (ngSubmit)="onSubmit()">
<div class="form-row" *ngFor="let control of dynamicControls">
<label [for]="control.key">{{ control.label | titlecase }}</label>
<form *ngIf="form" [ngClass]="options?.customClass" [formGroup]="form" (ngSubmit)="onSubmit()">
<div class="field form-row" *ngFor="let control of dynamicControls" [ngClass]="control.type">
<ng-container [ngSwitch]="control.type">
<input
#group
*ngSwitchDefault
[formControlName]="control.key"
[id]="control.key"
[style]="{ width: '100%', fontSize: '14px', height: '40px' }"
pInputText
type="control.type"
/>
<ng-container *ngSwitchCase="'checkbox'">
<p-checkbox
[formControlName]="control.key"
[binary]="true"
[id]="control.key"
></p-checkbox>
<label [for]="control.key">{{ control.label | titlecase }}</label>
</ng-container>
<ng-container *ngSwitchDefault>
<label [for]="control.key">{{ control.label | titlecase }}</label>
<input
#group
*ngSwitchDefault
[formControlName]="control.key"
[id]="control.key"
[type]="control.type"
[min]="control.min"
[style]="{ width: '100%', fontSize: '14px', height: '40px' }"
pInputText
type="control.type"
/>
</ng-container>
</ng-container>
<span
class="error-message"
Expand Down
Expand Up @@ -6,14 +6,22 @@
box-shadow: 0px 4px 10px rgba(10, 7, 37, 0.1);
display: flex;
flex-direction: column;
width: $form-width;
padding: $dot-editor-size;
}

form {
width: $form-width;
display: flex;
flex-direction: column;
gap: $dot-editor-size;

&.dotTableForm {
width: 200px;

.p-button-outlined {
display: none;
}
}
}

.form-row {
Expand All @@ -24,6 +32,11 @@ form {
label {
font-size: 0.75 * $dot-editor-size;
}

&.checkbox {
flex-direction: row;
align-items: center;
}
}

.form-action {
Expand Down
Expand Up @@ -20,6 +20,7 @@ export class BubbleFormComponent {
@Output() formValues = new EventEmitter();
@Output() hide = new EventEmitter<boolean>();

options: { customClass: string } = null;
dynamicControls: DynamicControl<unknown>[] = [];
form: FormGroup;

Expand All @@ -43,4 +44,8 @@ export class BubbleFormComponent {
);
});
}

cleanForm() {
this.form = null;
}
}

0 comments on commit 902c5a1

Please sign in to comment.