Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
3609f3a
Add config + change files to .ts
miina Sep 2, 2022
be63c46
Commit missing change
miina Sep 2, 2022
e2eede9
Merge main
miina Sep 5, 2022
6c8e09b
util.ts
miina Sep 5, 2022
3e72636
Formatters
miina Sep 5, 2022
da2cf1d
More types
miina Sep 5, 2022
a2b9d5b
More types.
miina Sep 6, 2022
080543e
Merge remote-tracking branch 'origin/main' into add/12179-typescript-…
miina Sep 6, 2022
9592bcc
Type state.
miina Sep 6, 2022
9deb517
Fix text.
miina Sep 7, 2022
05d48b2
Ignore ts
miina Sep 7, 2022
b3fab60
Update provider.ts
miina Sep 7, 2022
e96fb55
More types.
miina Sep 7, 2022
9bd12f2
Update context.ts
miina Sep 7, 2022
ce03a9b
More types
miina Sep 8, 2022
520dd08
Merge remote-tracking branch 'origin/main' into add/12179-typescript-…
miina Sep 8, 2022
fbe6e77
More type error fixes.
miina Sep 8, 2022
7026b32
Use DraftInlineStyle
miina Sep 8, 2022
6c4042b
One more DraftInlineStyle usage
miina Sep 8, 2022
c02797a
Use CSSProperties
miina Sep 8, 2022
298cfc1
Fix import
miina Sep 8, 2022
2775269
Override convertFromHTML type
miina Sep 8, 2022
75bfe9d
Try fixing pasting types.
miina Sep 9, 2022
45ce84a
Use Immutable Map for renderMap
miina Sep 12, 2022
da481f0
Move types for props to the relevant component files.
miina Sep 12, 2022
4664bd5
Use !== null instead of Boolean()
miina Sep 12, 2022
e26c93d
Use CSSProperties
miina Sep 12, 2022
b1f8ee0
Adjust styleMap to be a bit cleaner.
miina Sep 12, 2022
56c273b
Add function overload for useRichText()
miina Sep 12, 2022
14d8ccc
Init empty state with values
miina Sep 12, 2022
da066f2
Add Formatter interface
miina Sep 13, 2022
8b8ce75
Import immutable
miina Sep 13, 2022
8cd600e
Merge remote-tracking branch 'origin/main' into add/12179-typescript-…
miina Sep 13, 2022
fcdcbaa
Fix setter types.
miina Sep 13, 2022
b4ac830
Fix tests.
miina Sep 13, 2022
54e12c6
Use draft-js-export-html fork with built files
swissspidy Sep 13, 2022
7a892df
Adjust function overload for useRichText
miina Sep 13, 2022
68dcde8
Update lock file
swissspidy Sep 13, 2022
69374e7
Merge remote-tracking branch 'origin/main' into add/12179-typescript-…
miina Sep 13, 2022
b4fc5e2
Remove ts-ignore
miina Sep 13, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions packages/rich-text/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@
},
"customExports": {
".": {
"default": "./src/index.js"
"default": "./src/index.ts"
}
},
"main": "dist/index.js",
"module": "dist-module/index.js",
"source": "src/index.js",
"types": "dist-types/index.d.ts",
"source": "src/index.ts",
"publishConfig": {
"access": "public"
},
Expand All @@ -46,6 +47,7 @@
"prop-types": "^15.7.2"
},
"devDependencies": {
"@testing-library/react": "^12.1.5"
"@testing-library/react": "^12.1.5",
"@types/draft-js": "^0.11.9"
}
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@
* External dependencies
*/
import { stateToHTML } from 'draft-js-export-html';
import type { EditorState } from 'draft-js';

/**
* Internal dependencies
*/
import formatters from './formatters';

function inlineStyleFn(styles) {
function inlineStyleFn(styles: string[]) {
const inlineCSS = formatters.reduce(
(css, { stylesToCSS }) => ({ ...css, ...stylesToCSS(styles) }),
{}
Expand All @@ -40,13 +41,15 @@ function inlineStyleFn(styles) {
};
}

function exportHTML(editorState) {
function exportHTML(editorState: EditorState) {
if (!editorState) {
return null;
}

const html = stateToHTML(editorState.getCurrentContent(), {
inlineStyleFn,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment -- See the next line for reason.
// @ts-ignore Reason: `defaultBlockTag` is optional (undefined | string), however, `undefined` means `p` so we need to use `null` here.
defaultBlockTag: null,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,24 @@
* External dependencies
*/
import { stateFromHTML } from 'draft-js-import-html';
import type { InlineCreators } from 'draft-js-import-html';

/**
* Internal dependencies
*/
import getValidHTML from './utils/getValidHTML';
import formatters from './formatters';

function customInlineFn(element, { Style }) {
function customInlineFn(element: Element, { Style }: InlineCreators) {
const styleStrings = formatters
.map(({ elementToStyle }) => elementToStyle(element))
.map(({ elementToStyle }) => elementToStyle(element as HTMLElement))
.filter((style) => Boolean(style));

if (styleStrings.length === 0) {
return null;
}

// @todo Type of Style doesn't seem to be correct, check.
return Style(styleStrings);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
import formatters from './formatters';
import { fauxStylesToCSS } from './fauxSelection';

function customInlineDisplay(styles) {
// @todo Proper return type.
function customInlineDisplay(styles: string[]) {
const stylesToCSSConverters = [
...formatters.map(({ stylesToCSS }) => stylesToCSS),
fauxStylesToCSS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
* limitations under the License.
*/

/**
* External dependencies
*/
import type { EditorState } from 'draft-js';

/* Ignore reason: This is lifted from elsewhere - a combo of these basically:
*
* https://github.com/webdeveloperpr/draft-js-custom-styles/blob/f3e6b533905de8eee6da54f9727b5e5803d53fc4/src/index.js#L8-L52
Expand All @@ -39,11 +44,11 @@
* output: [Set("BOLD"), Set("BOLD", "ITALIC"), Set(), Set("UNDERLINE")]
* </example>
*
* @param {Object} editorState The current state of the editor including
* @param editorState The current state of the editor including
* selection
* @return {Array.<Set.<string>>} list of sets of styles as described
* @return list of sets of styles as described
*/
export function getAllStyleSetsInSelection(editorState) {
export function getAllStyleSetsInSelection(editorState: EditorState) {
const styleSets = [];
const contentState = editorState.getCurrentContent();
const selection = editorState.getSelection();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,30 @@
* External dependencies
*/
import { Editor, getDefaultKeyBinding, KeyBindingUtil } from 'draft-js';
import PropTypes from 'prop-types';
import {
useEffect,
useRef,
useImperativeHandle,
forwardRef,
useUnmount,
} from '@googleforcreators/react';
import type { ForwardedRef, KeyboardEvent } from 'react';

/**
* Internal dependencies
*/
import useRichText from './useRichText';
import customInlineDisplay from './customInlineDisplay';

function RichTextEditor({ content, onChange }, ref) {
interface RichTextEditorProps {
content: string;
onChange: (content: string) => void;
}

function RichTextEditor(
{ content, onChange }: RichTextEditorProps,
ref: ForwardedRef<HTMLElement>
) {
const editorRef = useRef(null);
const {
state: { editorState },
Expand Down Expand Up @@ -82,7 +90,7 @@ function RichTextEditor({ content, onChange }, ref) {

const { hasCommandModifier } = KeyBindingUtil;

function bindKeys(e) {
function bindKeys(e: KeyboardEvent) {
if (e.code === 'KeyA' && hasCommandModifier(e)) {
return 'selectall';
}
Expand All @@ -108,9 +116,4 @@ function RichTextEditor({ content, onChange }, ref) {

const RichTextEditorWithRef = forwardRef(RichTextEditor);

RichTextEditor.propTypes = {
content: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
};

export default RichTextEditorWithRef;
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@
*/
import { useEffect, useState } from '@googleforcreators/react';
import { EditorState, Modifier } from 'draft-js';
import type { SelectionState } from 'draft-js';
import type { Dispatch, SetStateAction } from 'react';

const FAUX_SELECTION = 'CUSTOM-FAUX';

function isEqualSelectionIgnoreFocus(a, b) {
function isEqualSelectionIgnoreFocus(
a: SelectionState | null,
b: SelectionState | null
) {
if (!a || !b) {
return false;
}
Expand All @@ -37,12 +42,16 @@ function isEqualSelectionIgnoreFocus(a, b) {
* If current selection in editor is unfocused, set faux style on current selection
* else, if current selection in editor is focused, remove faux style from entire editor
*
* @param {Object} editorState Current editor state
* @param {Function} setEditorState Callback to update current editor state
* @return {void}
* @param editorState Current editor state
* @param setEditorState Callback to update current editor state
*/
export function useFauxSelection(editorState, setEditorState) {
const [fauxSelection, setFauxSelection] = useState(null);
export function useFauxSelection(
editorState: EditorState | null,
setEditorState: Dispatch<SetStateAction<EditorState | null>>
) {
const [fauxSelection, setFauxSelection] = useState<SelectionState | null>(
null
);
useEffect(() => {
if (!editorState) {
setFauxSelection(null);
Expand Down Expand Up @@ -80,12 +89,15 @@ export function useFauxSelection(editorState, setEditorState) {
}

if (isFocused && hasSelectionChanged && hasFauxSelection) {
setEditorState((oldEditorState) => {
setEditorState((oldEditorState: EditorState | null) => {
try {
if (!oldEditorState) {
return null;
}
// Get new content with style removed from old selection
const contentWithoutFaux = Modifier.removeInlineStyle(
oldEditorState.getCurrentContent(),
fauxSelection,
fauxSelection as SelectionState,
FAUX_SELECTION
);

Expand Down Expand Up @@ -117,12 +129,17 @@ export function useFauxSelection(editorState, setEditorState) {
}, [fauxSelection, editorState, setEditorState]);
}

export function fauxStylesToCSS(styles, css) {
type Style = {
backgroundColor: string;
color?: string;
};

export function fauxStylesToCSS(styles: string[], css: Record<string, string>) {
const hasFauxSelection = styles.includes(FAUX_SELECTION);
if (!hasFauxSelection) {
return null;
}
const style = {
const style: Style = {
backgroundColor: 'rgba(169, 169, 169, 0.7)',
};
if (css?.color) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import {
isPatternEqual,
createSolidFromString,
} from '@googleforcreators/patterns';
import type { Pattern, Solid } from '@googleforcreators/patterns';
import type { EditorState } from 'draft-js';

/**
* Internal dependencies
Expand All @@ -40,11 +42,13 @@ import { isStyle, getVariable } from './util';
* Color uses PREFIX-XXXXXXXX where XXXXXXXX is the 8 digit
* hex represenation of the RGBA color.
*/
const styleToColor = (style) => getSolidFromHex(getVariable(style, COLOR));
const styleToColor = (style: string): Pattern =>
getSolidFromHex(getVariable(style, COLOR));

const colorToStyle = (color) => `${COLOR}-${getHexFromSolid(color)}`;
const colorToStyle = (color: Solid): string =>
`${COLOR}-${getHexFromSolid(color)}`;

function elementToStyle(element) {
function elementToStyle(element: HTMLElement): string | null {
const isSpan = element.tagName.toLowerCase() === 'span';
const rawColor = element.style.color;
const hasColor = Boolean(rawColor);
Expand All @@ -56,12 +60,12 @@ function elementToStyle(element) {
return null;
}

function stylesToCSS(styles) {
function stylesToCSS(styles: string[]): null | Record<string, unknown> {
const style = styles.find((someStyle) => isStyle(someStyle, COLOR));
if (!style) {
return null;
}
let color;
let color: Pattern;
try {
color = styleToColor(style);
} catch (e) {
Expand All @@ -71,7 +75,7 @@ function stylesToCSS(styles) {
return generatePatternStyles(color, 'color');
}

function getColor(editorState) {
function getColor(editorState: EditorState): Pattern | '((MULTIPLE))' {
const styles = getPrefixStylesInSelection(editorState, COLOR);
if (styles.length > 1) {
return MULTIPLE_VALUE;
Expand All @@ -83,7 +87,7 @@ function getColor(editorState) {
return styleToColor(colorStyle);
}

function setColor(editorState, color) {
function setColor(editorState: EditorState, color: Solid) {
// opaque black is default, and isn't necessary to set
const isBlack = isPatternEqual(createSolid(0, 0, 0), color);
const shouldSetStyle = () => !isBlack;
Expand Down
Loading