From 42ec663a0392b48ce81496f539460363359d8345 Mon Sep 17 00:00:00 2001 From: wxik_noohle Date: Thu, 4 Feb 2021 14:43:33 +0800 Subject: [PATCH] feat: setFontSize and setFontName --- CHANGELOG.md | 2 ++ examples/package.json | 3 ++- examples/src/example.js | 29 ++++++++++++++++++----------- examples/yarn.lock | 5 +++++ img/fontSize@2x.png | Bin 0 -> 1521 bytes img/fontSize@3x.png | Bin 0 -> 2335 bytes index.d.ts | 7 ++++++- src/RichEditor.js | 8 ++++++++ src/RichToolbar.js | 1 + src/const.js | 2 ++ src/editor.js | 16 +++++++++------- 11 files changed, 53 insertions(+), 20 deletions(-) create mode 100644 img/fontSize@2x.png create mode 100644 img/fontSize@3x.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 7422038..04ad65f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ #1.7.0 ### Added - Add h1,h2,h3,h4,h5,h6 State mapping +- `setFontSize` Changes the font size for the selection or at the insertion point. This requires an integer from 1-7 as a value argument. +- `setFontName` Changes the font name for the selection or at the insertion point. This requires a font name string (like "Arial") as a value argument. ### Fix - [Toolbar active/inactive](https://github.com/wxik/react-native-rich-editor/issues/141) diff --git a/examples/package.json b/examples/package.json index f28c299..459965d 100644 --- a/examples/package.json +++ b/examples/package.json @@ -14,7 +14,8 @@ "react-native": "0.63.4", "react-native-iphone-x-helper": "^1.3.1", "react-native-modal": "^11.6.1", - "react-native-webview": "^11.2.1" + "react-native-webview": "^11.2.1", + "@wxik/core": "^0.4.11" }, "devDependencies": { "@babel/core": "^7.12.13", diff --git a/examples/src/example.js b/examples/src/example.js index f7f21c5..fc29679 100644 --- a/examples/src/example.js +++ b/examples/src/example.js @@ -19,6 +19,7 @@ import { View, } from 'react-native'; import {actions, getContentCSS, RichEditor, RichToolbar} from 'react-native-pell-rich-editor'; +import {XMath} from '@wxik/core'; import {InsertLinkModal} from './insertLink'; import {EmojiView} from './emoji'; import {defaultActions} from '../../src'; @@ -37,9 +38,6 @@ const initHTML = `
Flutter
-
- -

Click the picture to switch

@@ -155,9 +153,20 @@ class Example extends React.Component { ); } + fontSize = () => { + // 1= 10px, 2 = 13px, 3 = 16px, 4 = 18px, 5 = 24px, 6 = 32px, 7 = 48px; + const size = [1, 2, 3, 4, 5, 6, 7]; + this.richText.current?.setFontSize(size[XMath.random(size.length - 1)]); + }; + insertHTML() { + // this.richText.current?.insertHTML( + // `HTML`, + // ); this.richText.current?.insertHTML( - `HTML`, + `
+ +
`, ); } @@ -228,17 +237,13 @@ class Example extends React.Component { let index = 0; switch (type) { case 'ImgClick': - index = this.i_tempIndex || 1; - this.i_tempIndex = index + 1 >= imageList.length ? 0 : index + 1; - this.richText.current?.commandDOM(`$('#${id}').src="${imageList[index]}"`); + this.richText.current?.commandDOM(`$('#${id}').src="${imageList[XMath.random(imageList.length - 1)]}"`); break; case 'TitleClick': - index = this._tempIndex || 0; - const color = ['red', 'blue', 'gray', 'yellow', 'coral'][index]; - this._tempIndex = index + 1 >= color.length ? 0 : index + 1; + const color = ['red', 'blue', 'gray', 'yellow', 'coral']; // command: $ = document.querySelector - this.richText.current?.commandDOM(`$('#${id}').style.color='${color}'`); + this.richText.current?.commandDOM(`$('#${id}').style.color='${color[XMath.random(color.length - 1)]}'`); break; case 'SwitchImage': break; @@ -361,6 +366,7 @@ class Example extends React.Component { actions.heading4, 'insertEmoji', 'insertHTML', + 'fontSize', ]} // default defaultActions iconMap={{ insertEmoji: phizIcon, @@ -375,6 +381,7 @@ class Example extends React.Component { insertEmoji={that.handleEmoji} insertHTML={that.insertHTML} insertVideo={that.insertVideo} + fontSize={that.fontSize} /> {emojiVisible && } diff --git a/examples/yarn.lock b/examples/yarn.lock index b01a02d..5788aa1 100644 --- a/examples/yarn.lock +++ b/examples/yarn.lock @@ -1121,6 +1121,11 @@ dependencies: "@types/yargs-parser" "*" +"@wxik/core@^0.4.11": + version "0.4.11" + resolved "https://registry.yarnpkg.com/@wxik/core/-/core-0.4.11.tgz#c241db13f03f1ada35489e0c2bf019399b6200da" + integrity sha512-sJIFLzxw8TPG+nZrskBnAszc0goGRxUu5vNzy304RPTTcAwbIzg6pRbC/q8JmAKNzQmSSdOEtAfbSxilikc7+Q== + abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" diff --git a/img/fontSize@2x.png b/img/fontSize@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4d3d3dfde2a0151dbfe6588fa9e448b818338ce9 GIT binary patch literal 1521 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 E2j689d;kCd literal 0 HcmV?d00001 diff --git a/index.d.ts b/index.d.ts index e0e0e62..f0cf21a 100644 --- a/index.d.ts +++ b/index.d.ts @@ -172,6 +172,11 @@ export class RichEditor extends React.Component { insertHTML: (html: string) => void; + /** + * 1 = 10px, 2 = 13px, 3 = 16px, 4 = 18px, 5 = 24px, 6 = 32px, 7 = 48px; + */ + setFontSize: (size: 1 | 2 | 3 | 4 | 5 | 6 | 7) => void; + /** * $ = document.querySelector * this.richText.current?.commandDOM(`$('#title').style.color='${color}'`); @@ -259,7 +264,7 @@ export interface RichToolbarProps { * Custom actions you want the toolbar to permit. * By default the toolbar permits an Action set of type DefaultActions */ - actions?: Partial | string[]; + actions?: Partial | string[]; } export class RichToolbar extends React.Component {} diff --git a/src/RichEditor.js b/src/RichEditor.js index 806668b..90a3499 100755 --- a/src/RichEditor.js +++ b/src/RichEditor.js @@ -361,6 +361,14 @@ export default class RichTextEditor extends Component { } } + setFontSize(size) { + this.sendAction(actions.fontSize, 'result', size); + } + + setFontName(name) { + this.sendAction(actions.fontName, 'result', name); + } + commandDOM(command) { if (command) { this.sendAction(actions.content, 'commandDOM', command); diff --git a/src/RichToolbar.js b/src/RichToolbar.js index 2506a06..aa5c3c1 100755 --- a/src/RichToolbar.js +++ b/src/RichToolbar.js @@ -41,6 +41,7 @@ function getDefaultIcon() { texts[actions.alignFull] = require('../img/justify_full.png'); texts[actions.blockquote] = require('../img/blockquote.png'); texts[actions.line] = require('../img/line.png'); + texts[actions.fontSize] = require('../img/fontSize.png'); return texts; } diff --git a/src/const.js b/src/const.js index 60a72d7..8ca2e68 100755 --- a/src/const.js +++ b/src/const.js @@ -27,6 +27,8 @@ export const actions = { insertHTML: 'html', insertImage: 'image', insertVideo: 'video', + fontSize: 'fontSize', + fontName: 'fontName', setSubscript: 'subscript', setSuperscript: 'superscript', setStrikethrough: 'strikeThrough', diff --git a/src/editor.js b/src/editor.js index b125c51..88e889a 100644 --- a/src/editor.js +++ b/src/editor.js @@ -242,13 +242,13 @@ function createHTML(options = {}) { italic: { state: function() { return queryCommandState('italic'); }, result: function() { return exec('italic'); }}, underline: { state: function() { return queryCommandState('underline'); }, result: function() { return exec('underline'); }}, strikeThrough: { state: function() { return queryCommandState('strikeThrough'); }, result: function() { return exec('strikeThrough'); }}, - heading1: { state: function() { return queryCommandState(formatBlock) === 'h1'; }, result: function() { return exec(formatBlock, '

'); }}, - heading2: { state: function() { return queryCommandState(formatBlock) === 'h2'; }, result: function() { return exec(formatBlock, '

'); }}, - heading3: { state: function() { return queryCommandState(formatBlock) === 'h3'; }, result: function() { return exec(formatBlock, '

'); }}, - heading4: { state: function() { return queryCommandState(formatBlock) === 'h4'; }, result: function() { return exec(formatBlock, '

'); }}, - heading5: { state: function() { return queryCommandState(formatBlock) === 'h5'; }, result: function() { return exec(formatBlock, '

'); }}, - heading6: { state: function() { return queryCommandState(formatBlock) === 'h6'; }, result: function() { return exec(formatBlock, '
'); }}, - paragraph: { state: function() { return queryCommandState(formatBlock) === 'p'; }, result: function() { return exec(formatBlock, '

'); }}, + heading1: { state: function() { return queryCommandValue(formatBlock) === 'h1'; }, result: function() { return exec(formatBlock, '

'); }}, + heading2: { state: function() { return queryCommandValue(formatBlock) === 'h2'; }, result: function() { return exec(formatBlock, '

'); }}, + heading3: { state: function() { return queryCommandValue(formatBlock) === 'h3'; }, result: function() { return exec(formatBlock, '

'); }}, + heading4: { state: function() { return queryCommandValue(formatBlock) === 'h4'; }, result: function() { return exec(formatBlock, '

'); }}, + heading5: { state: function() { return queryCommandValue(formatBlock) === 'h5'; }, result: function() { return exec(formatBlock, '

'); }}, + heading6: { state: function() { return queryCommandValue(formatBlock) === 'h6'; }, result: function() { return exec(formatBlock, '
'); }}, + paragraph: { state: function() { return queryCommandValue(formatBlock) === 'p'; }, result: function() { return exec(formatBlock, '

'); }}, quote: { result: function() { return exec(formatBlock, '

'); }}, removeFormat: { result: function() { return exec('removeFormat'); }}, orderedList: { @@ -272,6 +272,8 @@ function createHTML(options = {}) { justifyFull: { state: function() { return queryCommandState('justifyFull'); }, result: function() { return exec('justifyFull'); }}, hiliteColor: { state: function() { return queryCommandState('hiliteColor'); }, result: function(color) { return exec('hiliteColor', color); }}, foreColor: { state: function() { return queryCommandState('foreColor'); }, result: function(color) { return exec('foreColor', color); }}, + fontSize: { result: function(size) { return exec('fontSize', size); }}, + fontName: { result: function(name) { return exec('fontName', name); }}, link: { result: function(data) { data = data || {};