From 5501695f29414b9b38d86d0c53a8caa145a92e90 Mon Sep 17 00:00:00 2001 From: Dmitry S Date: Tue, 15 Mar 2022 10:53:39 -0400 Subject: [PATCH] Add a markdown type for Text cells. (WIP with loading external libraries etc.) --- app/client/widgets/MarkdownTextBox.ts | 41 +++++++++++++++++++++++++++ app/client/widgets/UserType.js | 8 ++++++ app/client/widgets/UserTypeImpl.js | 2 ++ static/app.html | 3 ++ 4 files changed, 54 insertions(+) create mode 100644 app/client/widgets/MarkdownTextBox.ts diff --git a/app/client/widgets/MarkdownTextBox.ts b/app/client/widgets/MarkdownTextBox.ts new file mode 100644 index 00000000..f95271cf --- /dev/null +++ b/app/client/widgets/MarkdownTextBox.ts @@ -0,0 +1,41 @@ +import {DataRowModel} from 'app/client/models/DataRowModel'; +import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec'; +import {colors} from 'app/client/ui2018/cssVars'; +import {NTextBox} from 'app/client/widgets/NTextBox'; +import {dom, styled} from 'grainjs'; + +/** + * Creates a widget for displaying links. Links can entered directly or following a title. + * The last entry following a space is used as the url. + * ie 'google https://www.google.com' would apears as 'google' to the user but link to the url. + */ +export class MarkdownTextBox extends NTextBox { + constructor(field: ViewFieldRec) { + super(field, {defaultTextColor: colors.lightGreen.value}); + } + + public buildDom(row: DataRowModel) { + const value = row.cells[this.field.colId()]; + return cssMarkdownField( + dom.style('text-align', this.alignment), + dom.cls('text_wrapping', this.wrapping), + dom.prop('innerHTML', (use) => + (window as any).DOMPurify.sanitize((window as any).marked(use(value))) + ), + ); + } +} + +const cssMarkdownField = styled('div.field_clip', ` + white-space: normal; + word-break: break-word; + line-height: 1.4; + & p:last-child { + margin-bottom: 0px; + } + & ul, & ol { + padding-left: 16px; + } + & li { + } +`); diff --git a/app/client/widgets/UserType.js b/app/client/widgets/UserType.js index ec95c1ad..63a7d3d1 100644 --- a/app/client/widgets/UserType.js +++ b/app/client/widgets/UserType.js @@ -73,6 +73,14 @@ var typeDefs = { options: { alignment: 'left', } + }, + Markdown: { + cons: 'MarkdownTextBox', + editCons: 'TextEditor', + icon: 'FieldTextbox', + options: { + alignment: 'left', + } } }, default: 'TextBox' diff --git a/app/client/widgets/UserTypeImpl.js b/app/client/widgets/UserTypeImpl.js index 9b942b66..3e8d702c 100644 --- a/app/client/widgets/UserTypeImpl.js +++ b/app/client/widgets/UserTypeImpl.js @@ -10,6 +10,7 @@ const {ReferenceEditor} = require('./ReferenceEditor'); const {ReferenceList} = require('./ReferenceList'); const {ReferenceListEditor} = require('./ReferenceListEditor'); const {HyperLinkTextBox} = require('./HyperLinkTextBox'); +const {MarkdownTextBox} = require('./MarkdownTextBox'); const {ChoiceTextBox } = require('./ChoiceTextBox'); const {Reference} = require('./Reference'); @@ -21,6 +22,7 @@ const nameToWidget = { 'TextEditor': NTextEditor, 'NumericTextBox': NumericTextBox, 'HyperLinkTextBox': HyperLinkTextBox, + 'MarkdownTextBox': MarkdownTextBox, 'HyperLinkEditor': HyperLinkEditor, 'Spinner': Spinner, 'CheckBox': require('./CheckBox'), diff --git a/static/app.html b/static/app.html index c62d76bf..adc1ff1e 100644 --- a/static/app.html +++ b/static/app.html @@ -14,6 +14,9 @@ + + + Grist