Skip to content
This repository was archived by the owner on Dec 10, 2025. It is now read-only.

Commit dac2831

Browse files
committed
feat(Add UMD, CJS, and ESM support): Add UMD, CJS, and ESM support
1 parent bc4c954 commit dac2831

19 files changed

Lines changed: 514 additions & 1589 deletions

.eslintrc.json

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,19 @@
3232
}
3333
},
3434
"rules": {
35-
"react/require-default-props": 0,
35+
"jsx-quotes": ["error","prefer-single"],
36+
"import/no-extraneous-dependencies": [
37+
"error",
38+
{
39+
"devDependencies": [
40+
".storybook/**",
41+
"stories/**"
42+
]
43+
}
44+
],
3645
"max-len": "off",
3746
"no-useless-return": "off",
38-
"jsx-quotes": ["error","prefer-single"],
39-
"react/jsx-filename-extension": "off"
47+
"react/jsx-filename-extension": "off",
48+
"react/require-default-props": 0
4049
}
4150
}

babel.config.js

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
module.exports = {
22
presets: [
3-
"@babel/preset-env",
4-
"@babel/preset-react",
5-
["@babel/preset-flow", { "all": true}]
3+
'@babel/preset-env',
4+
'@babel/preset-react',
5+
['@babel/preset-flow', { all: true }],
66
],
77
env: {
88
production: {
9-
plugins: [
10-
["react-remove-properties", { "properties": ["data-testid" ]}]
11-
]
12-
}
13-
}
9+
plugins: ['babel-plugin-jsx-remove-data-test-id'],
10+
},
11+
},
1412
};

package.json

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@
22
"name": "@lifechurch/react-draftable",
33
"version": "0.0.0-development",
44
"description": "A simple, customizable rich text editor built on Draft.js",
5-
"main": "dist/index.js",
5+
"main": "dist/react-draftable.cjs.js",
6+
"module": "dist/react-draftable.esm.js",
7+
"browser": "dist/react-draftable.umd.js",
68
"files": [
79
"dist",
8-
"LICENSE"
10+
"src"
911
],
1012
"scripts": {
11-
"build": "yarn clean && yarn build:parcel && yarn build:flow",
12-
"build:parcel": "cross-env NODE_ENV=production parcel build ./src/index.js --out-dir ./dist --out-file index.js --target node",
13-
"build:flow": "flow-copy-source src dist",
13+
"build": "yarn clean && yarn build:rollup",
14+
"build:rollup": "BABEL_ENV=production rollup -c --no-treeshake",
1415
"clean": "rimraf dist",
1516
"commit": "git-cz",
1617
"flow": "flow",
@@ -43,7 +44,7 @@
4344
"immutable": "^3.8.2"
4445
},
4546
"peerDependencies": {
46-
"draft-js": "x.10.x",
47+
"draft-js": "x.10.x | x.11.X",
4748
"react": "16.x.x",
4849
"react-dom": "16.x.x"
4950
},
@@ -60,9 +61,10 @@
6061
"babel-eslint": "^10.0.1",
6162
"babel-jest": "^24.8.0",
6263
"babel-loader": "^8.0.6",
63-
"babel-plugin-react-remove-properties": "^0.3.0",
64+
"babel-plugin-jsx-remove-data-test-id": "^2.0.0",
6465
"commitizen": "^3.1.1",
6566
"cross-env": "^5.2.0",
67+
"css-loader": "^2.1.1",
6668
"cz-conventional-changelog": "2.1.0",
6769
"draft-js": "^0.11.0-beta2",
6870
"eslint": "^5.16.0",
@@ -72,15 +74,22 @@
7274
"eslint-plugin-jsx-a11y": "^6.2.1",
7375
"eslint-plugin-react": "^7.13.0",
7476
"flow-bin": "^0.98.1",
75-
"flow-copy-source": "^2.0.6",
7677
"flow-inlinestyle": "^1.0.9",
7778
"jest": "^24.8.0",
7879
"jest-transform-stub": "^2.0.0",
79-
"parcel-bundler": "^1.12.3",
8080
"react": "^16.8.6",
8181
"react-dom": "^16.8.6",
8282
"react-testing-library": "^7.0.1",
8383
"rimraf": "^2.6.3",
84+
"rollup": "^1.12.5",
85+
"rollup-plugin-auto-external": "^2.0.0",
86+
"rollup-plugin-babel": "^4.3.2",
87+
"rollup-plugin-commonjs": "^10.0.0",
88+
"rollup-plugin-copy": "^2.0.1",
89+
"rollup-plugin-css-only": "^1.0.0",
90+
"rollup-plugin-multi-entry": "^2.1.0",
91+
"rollup-plugin-node-globals": "^1.4.0",
92+
"rollup-plugin-node-resolve": "^5.0.0",
8493
"semantic-release": "^15.13.12",
8594
"sinon": "^7.3.2"
8695
},

rollup.config.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import resolve from 'rollup-plugin-node-resolve';
2+
import commonjs from 'rollup-plugin-commonjs';
3+
import babel from 'rollup-plugin-babel';
4+
import css from 'rollup-plugin-css-only';
5+
import autoExternal from 'rollup-plugin-auto-external';
6+
import copy from 'rollup-plugin-copy';
7+
import pkg from './package.json';
8+
9+
const commonPlugins = [
10+
babel(),
11+
autoExternal(),
12+
resolve(),
13+
css({ output: 'dist/react-draftable.css' }),
14+
copy({
15+
targets: [
16+
'src/react-draftable.esm.js.flow',
17+
],
18+
outputFolder: 'dist',
19+
}),
20+
];
21+
22+
export default [
23+
// browser-friendly UMD build
24+
{
25+
input: 'src/index.js',
26+
output: {
27+
name: 'react-draftable',
28+
file: pkg.browser,
29+
format: 'umd',
30+
},
31+
plugins: [
32+
...commonPlugins,
33+
commonjs(),
34+
],
35+
},
36+
37+
// CommonJS (for Node) and ES module (for bundlers) build.
38+
{
39+
input: 'src/index.js',
40+
output: [
41+
{ file: pkg.main, format: 'cjs' },
42+
{ file: pkg.module, format: 'es' },
43+
],
44+
plugins: commonPlugins,
45+
},
46+
];

src/index.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ import {
77
Modifier,
88
getDefaultKeyBinding,
99
} from 'draft-js';
10+
import './styles.css';
11+
import './lib/DraftableState';
1012
import Toolbar, { defaultToolbarConfig, type ToolbarConfigType } from './toolbar';
11-
import 'draft-js/dist/Draft.css';
1213
import type { ToolbarButtonType } from './toolbarButton';
14+
import changeBlockDepth from './lib/changeBlockDepth';
15+
1316

1417
type DraftableProps = {
1518
initialState?: EditorState,
@@ -79,6 +82,18 @@ const Draftable = (
7982
case 'block':
8083
setEditorState(RichUtils.toggleBlockType(editorState, item.style));
8184
return;
85+
case 'indent': {
86+
const selection = editorState.getSelection();
87+
if (selection.isCollapsed()) {
88+
const content = editorState.getCurrentContent();
89+
const blockKey = selection.getStartKey();
90+
const block = content.getBlockForKey(blockKey);
91+
const depth = block.getDepth();
92+
const newState = changeBlockDepth(editorState, blockKey, depth + (item.style === 'indent' ? 1 : -1));
93+
setEditorState(newState);
94+
}
95+
break;
96+
}
8297
default:
8398
return;
8499
}

src/lib/BlockTypes.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ export const BLOCK_TYPES_LISTS:Array<ToolbarButtonType> = [
3232

3333
export const BLOCK_TYPES_INDENT:Array<ToolbarButtonType> = [
3434
{
35-
label: '->', style: 'indent', Icon: Indent, toggle: 'block', type: 'style',
35+
label: '->', style: 'indent', Icon: Indent, toggle: 'indent', type: 'style',
3636
},
3737
{
38-
label: '<-', style: 'outdent', Icon: Outdent, toggle: 'block', type: 'style',
38+
label: '<-', style: 'outdent', Icon: Outdent, toggle: 'indent', type: 'style',
3939
},
4040
];

src/lib/changeBlockDepth.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// @flow
2+
import { EditorState } from 'draft-js';
3+
4+
export default function changeBlockDepth(
5+
editorState: EditorState,
6+
blockKey: string,
7+
newDepth: number,
8+
): EditorState {
9+
const content = editorState.getCurrentContent();
10+
const block = content.getBlockForKey(blockKey);
11+
const depth = block.getDepth();
12+
13+
if (depth === newDepth) {
14+
return editorState;
15+
}
16+
17+
const newBlock = block.set('depth', newDepth);
18+
const newContent = content.merge({
19+
blockMap: content.getBlockMap().set(blockKey, newBlock),
20+
});
21+
return EditorState.push(
22+
editorState,
23+
newContent,
24+
'adjust-depth',
25+
);
26+
}

src/react-draftable.esm.js.flow

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// @flow
2+
import * as Draftable from '../src'; /* eslint-disable-line */

src/styles.css

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
@import '~draft-js/dist/Draft.css';
2+
3+
.public-DraftEditor-content {
4+
font-family: "Helvetica Neue", Helvetica, "Arial Nova", Arial, sans-serif;
5+
font-size: 16px;
6+
line-height: 1.25;
7+
}
8+
9+
.Toolbar-root {
10+
display: flex;
11+
margin: 14px 0;
12+
}
13+
14+
.ToolbarGroup-root {
15+
display: flex;
16+
}
17+
18+
.ToolbarGroup-root:not(:first-of-type):not(:last-of-type) {
19+
margin: 0 14px;
20+
}
21+
22+
.ToolbarButton-root {
23+
border: none;
24+
background: none;
25+
margin: 0 8px;
26+
padding: 0;
27+
}
28+
29+
.ToolbarButton-root:first-of-type {
30+
margin-left: 0;
31+
}

src/toolbar/index.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// @flow
22
import React from 'react';
3-
import './styles.css';
43
import { EditorState } from 'draft-js';
54
import ToolbarGroup, { type ToolbarGroupType } from '../toolbarGroup';
65
import type { ToolbarButtonType } from '../toolbarButton';
@@ -34,7 +33,13 @@ export default ({ editorState, toolbarConfig, onChange }:ToolbarProps) => {
3433
<div data-testid='toolbar' className='Toolbar-root'>
3534
{
3635
toolbarConfig.groups.map(group => (
37-
<ToolbarGroup key={group.key} items={toolbarConfig[group.key]} onChange={handleToggle} customStyles={group.customStyles} editorState={editorState} />
36+
<ToolbarGroup
37+
key={group.key}
38+
items={toolbarConfig[group.key]}
39+
onChange={handleToggle}
40+
customStyles={group.customStyles}
41+
editorState={editorState}
42+
/>
3843
))
3944
}
4045
</div>

0 commit comments

Comments
 (0)