Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 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.

2 changes: 1 addition & 1 deletion packages/patterns/src/generatePatternStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ function getStopList(stops: Array<ColorStop>, alpha: number) {
function generatePatternStyles(
pattern: Pattern | null = null,
property = 'background'
) {
): Record<string, string> {
if (pattern === null) {
return { [property]: 'transparent' };
}
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/useContextSelector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function useContextSelector<T, S>(

const equalityFnCallback = (state: T) => {
const selected = selector(state);
if (equalityFn(ref.current, selected)) {
if (ref.current && equalityFn(ref.current, selected)) {
return ref.current;
}
ref.current = selected;
Expand Down
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"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,16 @@
* External dependencies
*/
import { createContext } from '@googleforcreators/react';
/**
* Internal dependencies
*/
import type { State } from './types';

const RichTextContext = createContext({ state: {}, actions: {} });
// @todo Not sure how to use Partial correctly here to work with empty state and context selector.
// Should make all state and action values optional as before?
const RichTextContext = createContext<State>({
state: {},
actions: {},
} as State);

export default RichTextContext;
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 { DraftInlineStyle, EditorState } from 'draft-js';

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

function inlineStyleFn(styles) {
function inlineStyleFn(styles: DraftInlineStyle) {
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,25 @@
* 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;
}

// eslint-disable-next-line @typescript-eslint/ban-ts-comment -- The defined type is `string` but it actually accepts arrays of strings, too.
// @ts-ignore
return Style(styleStrings);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,19 @@
* limitations under the License.
*/

/**
* External dependencies
*/
import type { CSSProperties } from 'react';
import type { DraftInlineStyle } from 'draft-js';

/**
* Internal dependencies
*/
import formatters from './formatters';
import { fauxStylesToCSS } from './fauxSelection';

function customInlineDisplay(styles) {
function customInlineDisplay(styles: DraftInlineStyle): CSSProperties {
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,23 +18,28 @@
* External dependencies
*/
import { Editor, getDefaultKeyBinding, KeyBindingUtil } from 'draft-js';
import PropTypes from 'prop-types';
import type { EditorState } from 'draft-js';
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';
import type { RichTextEditorProps, State } from './types';

function RichTextEditor({ content, onChange }, ref) {
const editorRef = useRef(null);
function RichTextEditor(
{ content, onChange }: RichTextEditorProps,
ref: ForwardedRef<Partial<HTMLElement>>
) {
const editorRef = useRef<Editor | null>(null);
const {
state: { editorState },
actions: {
Expand All @@ -45,7 +50,7 @@ function RichTextEditor({ content, onChange }, ref) {
handlePastedText,
clearState,
},
} = useRichText();
} = useRichText() as State;

// Load state from parent when content changes
useEffect(() => {
Expand Down Expand Up @@ -82,7 +87,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 @@ -95,7 +100,8 @@ function RichTextEditor({ content, onChange }, ref) {
<Editor
ref={editorRef}
onChange={updateEditorState}
editorState={editorState}
/* We return before if EditorState is null so we know it's not null here */
editorState={editorState as EditorState}
handleKeyCommand={handleKeyCommand}
handlePastedText={handlePastedText}
keyBindingFn={bindKeys}
Expand All @@ -108,9 +114,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 { DraftInlineStyle, SelectionState } from 'draft-js';
import type { CSSProperties, 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,15 @@ export function useFauxSelection(editorState, setEditorState) {
}, [fauxSelection, editorState, setEditorState]);
}

export function fauxStylesToCSS(styles, css) {
export function fauxStylesToCSS(
styles: DraftInlineStyle,
css: Record<string, string>
) {
const hasFauxSelection = styles.includes(FAUX_SELECTION);
if (!hasFauxSelection) {
return null;
}
const style = {
const style: CSSProperties = {
backgroundColor: 'rgba(169, 169, 169, 0.7)',
};
if (css?.color) {
Expand Down
Loading