From d2236be11823a9af8118826fcc2704c9fe82fd9d Mon Sep 17 00:00:00 2001 From: robertu <4065233+robertu7@users.noreply.github.com> Date: Mon, 8 Jul 2024 17:36:05 +0800 Subject: [PATCH] feat(campaign): add campaign editor and normalizer; rename journal to moment; --- package.json | 2 +- src/editors/Campaign.tsx | 29 ++++++++++++++ src/editors/{Journal.tsx => Moment.tsx} | 14 +++---- src/editors/extensions/index.ts | 37 ++++++++++++++++-- src/editors/index.ts | 3 +- src/transformers/normalize.test.ts | 50 +++++++++++++++++++++++++ src/transformers/normalize.ts | 23 ++++++++++-- 7 files changed, 142 insertions(+), 16 deletions(-) create mode 100644 src/editors/Campaign.tsx rename src/editors/{Journal.tsx => Moment.tsx} (58%) diff --git a/package.json b/package.json index 5bedcc2..9f572ba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@matters/matters-editor", - "version": "0.2.5-alpha.8", + "version": "0.2.5-alpha.9", "description": "Editor for matters.news", "author": "https://github.com/thematters", "homepage": "https://github.com/thematters/matters-editor", diff --git a/src/editors/Campaign.tsx b/src/editors/Campaign.tsx new file mode 100644 index 0000000..53a3561 --- /dev/null +++ b/src/editors/Campaign.tsx @@ -0,0 +1,29 @@ +import { type EditorOptions, useEditor } from '@tiptap/react' + +import { + makeCampaignEditorExtensions, + type MakeCampaignEditorExtensionsProps, +} from './extensions' + +type UseCampaignEditorProps = { + content: string +} & MakeCampaignEditorExtensionsProps & + Partial + +export const useCampaignEditor = ({ + content, + placeholder, + ...editorProps +}: UseCampaignEditorProps) => { + const { extensions, ...restProps } = editorProps + const editor = useEditor({ + extensions: [ + ...makeCampaignEditorExtensions({ placeholder }), + ...(extensions ?? []), + ], + content, + ...restProps, + }) + + return editor +} diff --git a/src/editors/Journal.tsx b/src/editors/Moment.tsx similarity index 58% rename from src/editors/Journal.tsx rename to src/editors/Moment.tsx index 5fffdb5..b7e4e18 100644 --- a/src/editors/Journal.tsx +++ b/src/editors/Moment.tsx @@ -1,25 +1,25 @@ import { type EditorOptions, useEditor } from '@tiptap/react' import { - makeJournalEditorExtensions, - type MakeJournalEditorExtensionsProps, + makeMomentEditorExtensions, + type MakeMomentEditorExtensionsProps, } from './extensions' -type UseJournalEditorProps = { +type UseMomentEditorProps = { content: string -} & MakeJournalEditorExtensionsProps & +} & MakeMomentEditorExtensionsProps & Partial -export const useJournalEditor = ({ +export const useMomentEditor = ({ content, placeholder, mentionSuggestion, ...editorProps -}: UseJournalEditorProps) => { +}: UseMomentEditorProps) => { const { extensions, ...restProps } = editorProps const editor = useEditor({ extensions: [ - ...makeJournalEditorExtensions({ placeholder, mentionSuggestion }), + ...makeMomentEditorExtensions({ placeholder, mentionSuggestion }), ...(extensions ?? []), ], content, diff --git a/src/editors/extensions/index.ts b/src/editors/extensions/index.ts index 6497b5e..3022df4 100644 --- a/src/editors/extensions/index.ts +++ b/src/editors/extensions/index.ts @@ -111,17 +111,17 @@ export const makeCommentEditorExtensions = ({ } /** - * Journal + * Moment */ -export interface MakeJournalEditorExtensionsProps { +export interface MakeMomentEditorExtensionsProps { placeholder?: string mentionSuggestion?: MentionSuggestion } -export const makeJournalEditorExtensions = ({ +export const makeMomentEditorExtensions = ({ placeholder, mentionSuggestion, -}: MakeJournalEditorExtensionsProps) => { +}: MakeMomentEditorExtensionsProps) => { const extensions = [...baseExtensions(placeholder)] if (mentionSuggestion) { @@ -130,3 +130,32 @@ export const makeJournalEditorExtensions = ({ return extensions } + +/** + * Campaign + */ +export interface MakeCampaignEditorExtensionsProps { + placeholder?: string +} + +export const makeCampaignEditorExtensions = ({ + placeholder, +}: MakeCampaignEditorExtensionsProps) => { + return [ + Document, + History, + Placeholder.configure({ + placeholder, + }), + // Basic Formats + Text, + Paragraph, + HardBreak.configure({ + HTMLAttributes: { + class: 'smart', + }, + }), + // Custom Formats + Link, + ] +} diff --git a/src/editors/index.ts b/src/editors/index.ts index 31be665..af24936 100644 --- a/src/editors/index.ts +++ b/src/editors/index.ts @@ -1,4 +1,5 @@ export * from './Article' +export * from './Campaign' export * from './Comment' -export * from './Journal' +export * from './Moment' export * from '@tiptap/react' diff --git a/src/transformers/normalize.test.ts b/src/transformers/normalize.test.ts index eadc440..b9f44f3 100644 --- a/src/transformers/normalize.test.ts +++ b/src/transformers/normalize.test.ts @@ -3,6 +3,7 @@ import { describe, expect, test } from 'vitest' import { normalizeArticleHTML, + normalizeCampaignHTML, normalizeCommentHTML, NormalizeOptions, } from './normalize' @@ -25,6 +26,15 @@ const expectNormalizeCommentHTML = ( expect(result.trim()).toBe(output) } +const expectNormalizeCampaignHTML = ( + input: string, + output: string, + options?: NormalizeOptions, +) => { + const result = normalizeCampaignHTML(input, options) + expect(result.trim()).toBe(output) +} + /** * Tests */ @@ -439,3 +449,43 @@ describe('Normalization: Comment', () => { ) }) }) + +describe('Normalization: Campaign', () => { + test('quote is not supported', () => { + expectNormalizeCampaignHTML( + stripIndent` +
+

1

+

2

+

3

+
+ `, + '

1

2

3

', + ) + }) + + test('bold is not supported', () => { + expectNormalizeCampaignHTML('

abc

', '

abc

') + expectNormalizeCampaignHTML('

abc

', '

abc

') + }) + + test('strikethrough is not supported', () => { + expectNormalizeCampaignHTML('

abc

', '

abc

') + expectNormalizeCampaignHTML('

abc

', '

abc

') + expectNormalizeCampaignHTML('

abc

', '

abc

') + }) + + test('link is supported', () => { + expectNormalizeCampaignHTML( + '

abc

', + '

abc

', + ) + }) + + test('line break', () => { + expectNormalizeCampaignHTML( + '

hello,
world

', + '

hello,
world

', + ) + }) +}) diff --git a/src/transformers/normalize.ts b/src/transformers/normalize.ts index 84da7fa..ba585f4 100644 --- a/src/transformers/normalize.ts +++ b/src/transformers/normalize.ts @@ -6,8 +6,9 @@ import { createHTMLDocument, parseHTML, type VHTMLDocument } from 'zeed-dom' import { makeArticleEditorExtensions, + makeCampaignEditorExtensions, makeCommentEditorExtensions, - makeJournalEditorExtensions, + makeMomentEditorExtensions, Mention, } from '../editors/extensions' @@ -100,11 +101,11 @@ export const normalizeCommentHTML = ( return normalizedHtml } -export const normalizeJournalHTML = ( +export const normalizeMomentHTML = ( html: string, options?: NormalizeOptions, ): string => { - const extensions = makeJournalEditorExtensions({}) + const extensions = makeMomentEditorExtensions({}) const normalizer = makeNormalizer([...extensions, Mention]) let normalizedHtml = normalizer(html) @@ -115,3 +116,19 @@ export const normalizeJournalHTML = ( return normalizedHtml } + +export const normalizeCampaignHTML = ( + html: string, + options?: NormalizeOptions, +): string => { + const extensions = makeCampaignEditorExtensions({}) + const normalizer = makeNormalizer(extensions) + + let normalizedHtml = normalizer(html) + + if (options?.truncate) { + normalizedHtml = truncateLinkText(normalizedHtml, options.truncate) + } + + return normalizedHtml +}