-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: create tiptap language extension
- Loading branch information
1 parent
8125607
commit 2076ad1
Showing
10 changed files
with
255 additions
and
4 deletions.
There are no files selected for viewing
47 changes: 47 additions & 0 deletions
47
packages/strapi-tiptap-editor/admin/src/components/Editor/LanguagesList.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { Option, Select } from '@strapi/design-system/Select'; | ||
import type { Editor as EditorTypes } from '@tiptap/react'; | ||
import React from 'react'; | ||
import { useIntl } from 'react-intl'; | ||
import getTrad from '../../utils/getTrad'; | ||
|
||
interface LanguagesListProps { | ||
editor: EditorTypes; | ||
languages: { titleKey: string; languageCode: string }[]; | ||
selectField: { | ||
placeholder?: string; | ||
removeLanguageOption: string; | ||
}; | ||
} | ||
|
||
export const LanguagesList = ({ editor, languages, selectField }: LanguagesListProps) => { | ||
const { formatMessage } = useIntl(); | ||
return ( | ||
<Select | ||
size="S" | ||
placeholder={selectField?.placeholder} | ||
value={editor.isActive('language') ? editor.getAttributes('language').lang : ''} | ||
onChange={(event: string | number) => { | ||
if (editor) { | ||
if (event === 'remove_language') { | ||
editor.chain().focus().unsetLanguage().run(); | ||
return; | ||
} | ||
editor | ||
.chain() | ||
.focus() | ||
.toggleLanguage({ lang: event as string }) | ||
.run(); | ||
} | ||
}} | ||
> | ||
<Option value="remove_language">{selectField.removeLanguageOption}</Option> | ||
{languages && | ||
languages.length > 0 && | ||
languages.map(({ languageCode, titleKey }) => ( | ||
<Option key={languageCode} className="icon" value={languageCode}> | ||
{formatMessage({ id: getTrad(titleKey) })} | ||
</Option> | ||
))} | ||
</Select> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
143 changes: 143 additions & 0 deletions
143
packages/strapi-tiptap-editor/admin/src/components/extensions/Language/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
/* eslint-disable no-unused-vars */ | ||
import { Mark, markInputRule, markPasteRule, mergeAttributes } from '@tiptap/core'; | ||
|
||
export interface LanguageOptions { | ||
HTMLAttributes: Record<string, any>; | ||
} | ||
|
||
declare module '@tiptap/core' { | ||
interface Commands<ReturnType> { | ||
language: { | ||
/** | ||
* Set the language attribute | ||
*/ | ||
setLanguage: (attributes?: { lang: string }) => ReturnType; | ||
/** | ||
* Toggle the language attribute | ||
*/ | ||
toggleLanguage: (attributes?: { lang: string }) => ReturnType; | ||
/** | ||
* Unset the language attribute | ||
*/ | ||
unsetLanguage: () => ReturnType; | ||
}; | ||
} | ||
} | ||
|
||
export const inputRegex = /(?:^|\s)((?:==)((?:[^~=]+))(?:==))$/; | ||
export const pasteRegex = /(?:^|\s)((?:==)((?:[^~=]+))(?:==))/g; | ||
|
||
export const Language = Mark.create<LanguageOptions>({ | ||
name: 'language', | ||
|
||
addOptions() { | ||
return { | ||
HTMLAttributes: {}, | ||
}; | ||
}, | ||
|
||
addAttributes() { | ||
return { | ||
lang: { | ||
default: null, | ||
parseHTML: (element) => { | ||
return element.getAttribute('lang') || null; | ||
}, | ||
renderHTML: (attributes) => { | ||
if (!attributes.lang) { | ||
return {}; | ||
} | ||
return { | ||
lang: attributes.lang, | ||
dir: getDirectionFromLanguageCode(attributes.lang), | ||
}; | ||
}, | ||
}, | ||
}; | ||
}, | ||
|
||
parseHTML() { | ||
return [ | ||
{ | ||
tag: 'span[lang][dir]', | ||
}, | ||
]; | ||
}, | ||
|
||
renderHTML({ HTMLAttributes }) { | ||
return ['span', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; | ||
}, | ||
|
||
addCommands() { | ||
return { | ||
setHighlight: | ||
(attributes) => | ||
({ commands }) => { | ||
return commands.setMark(this.name, attributes); | ||
}, | ||
toggleLanguage: | ||
(attributes) => | ||
({ commands }) => { | ||
return commands.toggleMark(this.name, attributes); | ||
}, | ||
unsetLanguage: | ||
() => | ||
({ commands }) => { | ||
return commands.unsetMark(this.name); | ||
}, | ||
}; | ||
}, | ||
|
||
addInputRules() { | ||
return [ | ||
markInputRule({ | ||
find: inputRegex, | ||
type: this.type, | ||
}), | ||
]; | ||
}, | ||
|
||
addPasteRules() { | ||
return [ | ||
markPasteRule({ | ||
find: pasteRegex, | ||
type: this.type, | ||
}), | ||
]; | ||
}, | ||
}); | ||
|
||
// TODO create utils package and move this logic there | ||
function getDirectionFromLanguageCode(languageCode: string): 'ltr' | 'rtl' { | ||
// List of language codes that are written right-to-left | ||
const rtlLanguages = [ | ||
'ar', | ||
'he', | ||
'fa', | ||
'ur', | ||
'yi', | ||
'dv', | ||
'ps', | ||
'ku', | ||
'ug', | ||
'arc', | ||
'azb', | ||
'mzn', | ||
'pnb', | ||
'sd', | ||
'ckb', | ||
'lrc', | ||
'glk', | ||
'nv', | ||
'prs', | ||
'tmr', | ||
'uga', | ||
]; | ||
// Check if the language code is in the list of RTL languages | ||
if (rtlLanguages.includes(languageCode.toLowerCase())) { | ||
return 'rtl'; | ||
} | ||
|
||
// Default to left-to-right if not in the list of RTL languages | ||
return 'ltr'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,7 @@ | ||
{} | ||
{ | ||
"components.languagesList.placeholder": "Select a language", | ||
"components.languagesList.removeLanguage": "Remove Language", | ||
"languages.dutch": "Dutch", | ||
"languages.english": "English", | ||
"languages.arabic": "Arabic" | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"components.languagesList.placeholder": "Selecteer een taal", | ||
"components.languagesList.removeLanguage": "Taal verwijderen", | ||
"languages.dutch": "Nederlands", | ||
"languages.english": "Engels", | ||
"languages.arabic": "Arabisch" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,7 @@ export default { | |
}, | ||
other: { | ||
wordcount: false, | ||
language: true, | ||
saveJson: false, | ||
}, | ||
youtube: { | ||
|