react-simple-wysiwyg
Version:
Simple and lightweight React WYSIWYG editor
1 lines âĒ 37 kB
Source Map (JSON)
{"version":3,"file":"index.umd.min.js","sources":["../../node_modules/tslib/tslib.es6.js","../../src/utils.ts","../../src/ContentEditable.tsx","../../src/styles.ts","../../src/Editor.tsx","../../src/toolbar/buttons.tsx","../../src/toolbar/icons/OrderedListIcon.tsx","../../src/toolbar/icons/UnorderedListIcon.tsx","../../src/toolbar/dropdowns.tsx","../../src/toolbar/Separator.tsx","../../src/toolbar/Toolbar.tsx","../../src/DefaultEditor.tsx"],"sourcesContent":["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation. All rights reserved.\r\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use\r\nthis file except in compliance with the License. You may obtain a copy of the\r\nLicense at http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\r\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\r\nMERCHANTABLITY OR NON-INFRINGEMENT.\r\n\r\nSee the Apache Version 2.0 License for specific language governing permissions\r\nand limitations under the License.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)\r\n t[p[i]] = s[p[i]];\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport function __exportStar(m, exports) {\r\n for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nexport function __values(o) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator], i = 0;\r\n if (m) return m.call(o);\r\n return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result.default = mod;\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n","export function compare<T>(a: T, b: T, keys: Array<keyof T>): boolean {\n return keys.every((key) => {\n return a[key] === b[key];\n });\n}\n\nexport function deepMerge<T>(target, ...sources: T[]): T {\n if (!sources.length) {\n return target;\n }\n\n const source = sources.shift();\n\n if (isObject(target) && isObject(source)) {\n for (const key in source) {\n if (!source.hasOwnProperty(key)) {\n continue;\n }\n\n if (isObject(source[key])) {\n if (!target[key]) {\n Object.assign(target, { [key]: {} });\n }\n\n deepMerge(target[key], source[key]);\n } else {\n Object.assign(target, { [key]: source[key] });\n }\n }\n }\n\n return deepMerge(target, ...sources);\n}\n\nexport function findLastTextNode(node: Node): Node | null {\n if (node.nodeType === Node.TEXT_NODE) {\n return node;\n }\n\n const children = node.childNodes;\n for (let i = children.length - 1; i >= 0; i--) {\n const textNode = findLastTextNode(children[i]);\n\n if (textNode !== null) {\n return textNode;\n }\n }\n return null;\n}\n\nexport function getSelectedNode(): Node {\n if ((document as any).selection) {\n return (document as any).selection.createRange().parentElement();\n }\n\n const selection = window.getSelection();\n if (selection.rangeCount > 0) {\n return selection.getRangeAt(0).startContainer.parentNode;\n }\n}\n\nfunction isObject(item) {\n return (item && typeof item === 'object' && !Array.isArray(item));\n}\n\nexport function normalizeHtml(str: string): string {\n return str && str.replace(/ |\\u202F|\\u00A0/g, ' ');\n}\n\nexport function replaceCaret(el: HTMLElement) {\n // Place the caret at the end of the element\n const target = findLastTextNode(el);\n // do not move caret if element was not focused\n const isTargetFocused = document.activeElement === el;\n\n if (target !== null && target.nodeValue !== null && isTargetFocused) {\n const range = document.createRange();\n const sel = window.getSelection();\n range.setStart(target, target.nodeValue.length);\n range.collapse(true);\n sel.removeAllRanges();\n sel.addRange(range);\n\n if (el instanceof HTMLElement) {\n el.focus();\n }\n }\n}\n","import { Component, createElement, HTMLAttributes } from 'react';\nimport * as React from 'react';\nimport { compare, normalizeHtml, replaceCaret } from './utils';\n\n/**\n * Based on https://github.com/lovasoa/react-contenteditable\n * A simple component for an html element with editable contents.\n */\nexport default class ContentEditable extends Component<ICEProps> {\n el: HTMLElement;\n previousValue: string;\n\n constructor(props: ICEProps) {\n super(props);\n\n this.previousValue = props.value;\n\n this.onChange = this.onChange.bind(this);\n this.setElementRef = this.setElementRef.bind(this);\n }\n\n shouldComponentUpdate(nextProps: ICEProps): boolean {\n const props = this.props;\n\n if (!this.el) {\n return true;\n }\n\n if (normalizeHtml(nextProps.value) !== normalizeHtml(this.el.innerHTML)) {\n return true;\n }\n\n return !compare(props, nextProps, ['disabled', 'tagName', 'className']);\n }\n\n componentDidUpdate() {\n if (!this.el) {\n return;\n }\n\n if (this.props.value !== this.el.innerHTML) {\n this.previousValue = this.props.value;\n this.el.innerHTML = this.props.value;\n }\n\n replaceCaret(this.el);\n }\n\n setElementRef(el) {\n const { contentEditableRef } = this.props;\n this.el = el;\n\n contentEditableRef && contentEditableRef(el);\n }\n\n onChange(event: React.FormEvent<HTMLElement>) {\n if (!this.el) {\n return;\n }\n\n const value = this.el.innerHTML;\n const previous = this.previousValue;\n this.previousValue = value;\n\n if (this.props.onChange && value !== previous) {\n this.props.onChange({ ...event, target: { value } as any });\n }\n }\n\n render() {\n const { contentEditableRef, tagName, value, ...props } = this.props;\n\n return createElement(tagName || 'div', {\n ...props,\n contentEditable: !this.props.disabled,\n dangerouslySetInnerHTML: { __html: value },\n onBlur: this.props.onBlur || this.onChange,\n onInput: this.onChange,\n onKeyDown: this.props.onKeyDown || this.onChange,\n onKeyUp: this.props.onKeyUp || this.onChange,\n ref: this.setElementRef,\n });\n }\n}\n\nexport interface ICEProps extends HTMLAttributes<HTMLElement> {\n disabled?: boolean;\n contentEditableRef?: (el: HTMLElement) => void;\n tagName?: string;\n value?: string;\n}\n","import { CSSProperties } from 'react';\n\nconst styles = {\n button: {\n normal: {\n backgroundColor: 'unset',\n border: 'none',\n color: '#222',\n height: 24,\n outline: 'none',\n padding: 0,\n verticalAlign: 'top',\n width: 24,\n },\n\n hovered: {\n backgroundColor: '#eaeaea',\n },\n\n active: {\n backgroundColor: '#e0e0e0',\n },\n },\n\n contentEditable: {\n flex: 1,\n outline: 'none',\n padding: 5,\n },\n\n dropdown: {\n boxSizing: 'border-box' as any,\n height: 20,\n marginTop: 2,\n outline: 'none',\n verticalAlign: 'top',\n },\n\n editor: {\n border: '1px solid #ddd',\n borderRadius: 3,\n display: 'flex',\n flexDirection: 'column' as any,\n minHeight: 100,\n },\n\n separator: {\n backgroundColor: '#ddd',\n display: 'inline-block',\n height: 20,\n margin: 2,\n verticalAlign: 'top',\n width: 1,\n },\n};\n\nexport default styles;\n\ntype CssCollection<T> = {\n [P in keyof T]?: CSSProperties | CssCollection<T[P]>;\n};\n\nexport type IStyles = typeof styles;\nexport type IEditorStyles = CssCollection<IStyles>;\n","import {\n ComponentType,\n createContext,\n PureComponent,\n SyntheticEvent,\n} from 'react';\nimport * as React from 'react';\nimport ContentEditable, { ICEProps } from './ContentEditable';\nimport defaultStyles, { IEditorStyles, IStyles } from './styles';\nimport { deepMerge, getSelectedNode } from './utils';\n\nexport const EditorContext = createContext<IEditorContext>({\n styles: defaultStyles,\n});\n\nexport default class Editor extends PureComponent<IEditorProps, IState> {\n constructor(props: IEditorProps) {\n super(props);\n\n this.state = {};\n\n this.onClickOutside = this.onClickOutside.bind(this);\n this.onTextSelect = this.onTextSelect.bind(this);\n this.setContentEditableRef = this.setContentEditableRef.bind(this);\n }\n\n componentDidMount() {\n document.addEventListener('click', this.onClickOutside);\n }\n\n componentWillUnmount() {\n document.removeEventListener('click', this.onClickOutside);\n }\n\n setContentEditableRef(el: HTMLElement) {\n this.setState({ contentEditable: el });\n this.props.contentEditableRef && this.props.contentEditableRef(el);\n }\n\n onClickOutside(event: MouseEvent) {\n const { contentEditable } = this.state;\n\n if (event.target === contentEditable) {\n return;\n }\n\n if (contentEditable && contentEditable.contains(event.target as any)) {\n return;\n }\n\n this.setState({ selection: null });\n }\n\n onTextSelect(e: SyntheticEvent<HTMLElement>) {\n this.props.onSelect && this.props.onSelect(e);\n this.setState({ selection: getSelectedNode() });\n }\n\n render() {\n const { children, styles, ...props } = this.props;\n const { contentEditable, selection } = this.state;\n\n const allStyles = deepMerge({}, defaultStyles, styles as any);\n\n const context: IEditorContext = {\n el: contentEditable,\n selection,\n styles: allStyles,\n };\n\n return (\n <div style={context.styles.editor}>\n <EditorContext.Provider value={context}>\n {children}\n <ContentEditable\n {...props}\n contentEditableRef={this.setContentEditableRef}\n onSelect={this.onTextSelect}\n style={allStyles.contentEditable}\n />\n </EditorContext.Provider>\n </div>\n );\n }\n}\n\nexport function withEditorContext<T extends ComponentType<any>>(\n Component: T,\n): T {\n\n WithEditorContext.displayName =\n `withEditorContext(${Component.displayName || Component.name})`;\n\n return WithEditorContext as any;\n\n function WithEditorContext(props) {\n return (\n <EditorContext.Consumer>\n {(context: IEditorContext) => (\n <Component\n {...props}\n el={context.el}\n selection={context.selection}\n styles={context.styles}\n />\n )}\n </EditorContext.Consumer>\n );\n }\n}\n\nexport interface IEditorProps extends ICEProps {\n styles?: IEditorStyles;\n}\n\nexport interface IEditorContext {\n el?: HTMLElement;\n selection?: Node;\n styles?: IStyles;\n}\n\ninterface IState {\n contentEditable?: HTMLElement;\n selection?: Node;\n}\n","import { CSSProperties, HTMLAttributes, ReactNode, useState } from 'react';\nimport * as React from 'react';\nimport { IEditorContext, withEditorContext } from '../Editor';\nimport OrderedListIcon from './icons/OrderedListIcon';\nimport UnorderedListIcon from './icons/UnorderedListIcon';\n\n// tslint:disable:max-line-length\n\nexport const BtnBold = createButton('Bold', 'ð', 'bold');\nexport const BtnClearFormatting = createButton('Clear formatting', 'TĖēâ', 'removeFormat');\nexport const BtnItalic = createButton('Italic', 'ð°', 'italic');\nexport const BtnLink = createButton('Link', 'ð', (selected: Node) => {\n if (selected && selected.nodeName === 'A') {\n document.execCommand('unlink');\n } else {\n document.execCommand('createLink', false, prompt('URL'));\n }\n});\nexport const BtnNumberedList = createButton('Numbered list', <OrderedListIcon />, 'insertOrderedList');\nexport const BtnRedo = createButton('Redo', 'â·', 'redo');\nexport const BtnUnderline = createButton('Underline', <span style={{ textDecoration: 'underline' }}>ð</span>, 'underline');\nexport const BtnUndo = createButton('Undo', 'âķ', 'undo');\nexport const BtnBulletList = createButton('Bullet list', <UnorderedListIcon />, 'insertUnorderedList');\n\nexport function Button(props: IButtonProps) {\n const [ hovered, setHovered ] = useState(false);\n\n const { active, styles, el, selection, ...inputProps } = props;\n\n const style = {\n ...styles.button.normal,\n ...props.style,\n ...(hovered ? styles.button.hovered : {}),\n ...(hovered ? props.hoverStyle : {}),\n ...(active ? styles.button.active : {}),\n };\n\n const onHover = (e) => {\n setHovered(true);\n props.onMouseEnter && props.onMouseEnter(e);\n };\n\n const onUnHover = (e) => {\n setHovered(false);\n props.onMouseLeave && props.onMouseLeave(e);\n };\n\n return (\n <button\n {...inputProps}\n style={style}\n onMouseEnter={onHover}\n onMouseLeave={onUnHover}\n />\n );\n}\n\nexport interface IButtonProps\n extends HTMLAttributes<HTMLButtonElement>, IEditorContext {\n active?: boolean;\n hoverStyle?: CSSProperties;\n}\n\nfunction createButton(\n title: string,\n content: ReactNode,\n command: ((selection: Node) => void) | string,\n): typeof Button {\n ButtonFactory.displayName = title.replace(/\\s/g, '');\n\n return withEditorContext<typeof Button>(ButtonFactory);\n\n function ButtonFactory(props: IButtonProps) {\n const { selection, ...buttonProps } = props;\n\n let active = false;\n if (typeof command === 'string') {\n active = !!selection && document.queryCommandState(command);\n }\n\n return (\n <Button title={title} {...buttonProps} onMouseDown={action} active={active}>\n {content}\n </Button>\n );\n\n function action() {\n if (typeof command === 'function') {\n command(selection);\n } else {\n document.execCommand(command);\n }\n }\n }\n}\n","import * as React from 'react';\n\nexport default function OrderedListIcon() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n style={{ verticalAlign: 'text-top' }}\n >\n <path\n fill=\"currentColor\"\n d=\"M 6.99938,12.998L 6.99938,10.998L 20.9994,10.998L 20.9994,12.998L 6.99938,12.998 Z M 6.99938,18.9981L 6.99938,16.9981L 20.9994,16.9981L 20.9994,18.9981L 6.99938,18.9981 Z M 6.99938,6.99809L 6.99938,4.99809L 20.9994,4.99809L 20.9994,6.99809L 6.99938,6.99809 Z M 2.99938,7.99809L 2.99938,4.99809L 1.99938,4.99809L 1.99938,3.99809L 3.99938,3.99809L 3.99938,7.99809L 2.99938,7.99809 Z M 1.99938,16.9981L 1.99938,15.9981L 4.99938,15.9981L 4.99938,19.9981L 1.99938,19.9981L 1.99938,18.9981L 3.99938,18.9981L 3.99938,18.4981L 2.99938,18.4981L 2.99938,17.4981L 3.99938,17.4981L 3.99938,16.9981L 1.99938,16.9981 Z M 4.25,10C 4.66421,10 5,10.3358 5,10.75C 5,10.9524 4.91983,11.1361 4.7895,11.271L 3.11983,13L 5,13L 5,14L 2,14L 2,13.0782L 4,11L 2,11L 2,10L 4.25,10 Z \"\n />\n </svg>\n );\n}\n","import * as React from 'react';\n\nexport default function UnorderedListIcon() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n style={{ verticalAlign: 'text-top'}}\n >\n <path\n fill=\"currentColor\"\n d=\"M 7,5L 21,5L 21,7L 7,7L 7,5 Z M 7,13L 7,11L 21,11L 21,13L 7,13 Z M 4,4.50001C 4.83,4.50001 5.5,5.16993 5.5,6.00001C 5.5,6.83008 4.83,7.50001 4,7.50001C 3.17,7.50001 2.5,6.83008 2.5,6.00001C 2.5,5.16993 3.17,4.50001 4,4.50001 Z M 4,10.5C 4.83,10.5 5.5,11.17 5.5,12C 5.5,12.83 4.83,13.5 4,13.5C 3.17,13.5 2.5,12.83 2.5,12C 2.5,11.17 3.17,10.5 4,10.5 Z M 7,19L 7,17L 21,17L 21,19L 7,19 Z M 4,16.5C 4.83,16.5 5.5,17.17 5.5,18C 5.5,18.83 4.83,19.5 4,19.5C 3.17,19.5 2.5,18.83 2.5,18C 2.5,17.17 3.17,16.5 4,16.5 Z \"\n />\n</svg>\n );\n}\n","import { ChangeEvent, HTMLAttributes } from 'react';\nimport * as React from 'react';\nimport { IEditorContext, withEditorContext } from '../Editor';\n\nexport const BtnStyles = createDropdown('Styles', [\n ['Normal', 'formatBlock', 'DIV'],\n ['ððēðŪðąðēðŋ ð', 'formatBlock', 'H1'],\n ['Header 2', 'formatBlock', 'H2'],\n ['ðēððð', 'formatBlock', 'PRE'],\n]);\n\nfunction createDropdown(\n title: string,\n items: IDropDownItem[],\n): typeof Dropdown {\n DropdownFactory.displayName = title;\n\n return withEditorContext<typeof Dropdown>(DropdownFactory);\n\n function DropdownFactory(props: IDropdownProps) {\n const { selection, ...ddProps } = props;\n\n return (\n <Dropdown {...ddProps} onChange={onChange} title={title} items={items} />\n );\n\n function onChange(e: ChangeEvent<HTMLSelectElement>) {\n const selected = parseInt(e.target.value, 10);\n const [, command, commandArgument] = items[selected];\n\n e.preventDefault();\n e.target.selectedIndex = 0;\n\n if (typeof command === 'function') {\n command(selection);\n } else {\n document.execCommand(command, false, commandArgument);\n }\n }\n }\n}\n\nexport function Dropdown(props: IDropdownProps) {\n const { el, items, selected, selection, styles, ...inputProps } = props;\n\n const style = { ...styles.dropdown, ...props.style };\n\n return (\n <select {...inputProps} value={selected} style={style}>\n <option hidden>{props.title}</option>\n {items.map((item, index) => (\n <option key={index} value={index}>{item[0]}</option>\n ))}\n </select>\n );\n}\n\nexport interface IDropdownProps\n extends HTMLAttributes<HTMLSelectElement>, IEditorContext {\n selected?: number;\n items?: IDropDownItem[];\n}\n\ntype IDropDownItem = [string, string | ((selection: Node) => void), string?];\n","import * as React from 'react';\nimport { IEditorContext, withEditorContext } from '../Editor';\n\nfunction Separator(context: IEditorContext) {\n return (\n <span style={context.styles.separator} />\n );\n}\n\nconst WrappedSeparator = withEditorContext(Separator);\nexport default WrappedSeparator;\n","import * as React from 'react';\n\nexport default function Toolbar(props: React.HTMLAttributes<HTMLDivElement>) {\n const rootStyle = {\n ...styles.root,\n ...props.style,\n };\n\n return (\n <div {...props} style={rootStyle}/>\n );\n}\n\nconst styles = {\n root: {\n backgroundColor: '#f5f5f5',\n borderBottom: '1px solid #ddd',\n },\n};\n","import * as React from 'react';\nimport Editor, { IEditorProps } from './Editor';\nimport {\n BtnBold,\n BtnBulletList,\n BtnClearFormatting,\n BtnItalic,\n BtnLink,\n BtnNumberedList,\n BtnRedo,\n BtnStyles,\n BtnUnderline,\n BtnUndo,\n Separator,\n Toolbar,\n} from './toolbar';\n\nexport default function DefaultEditor(props: IEditorProps) {\n return (\n <Editor {...props}>\n <Toolbar>\n <BtnUndo />\n <BtnRedo />\n <Separator />\n <BtnBold />\n <BtnItalic />\n <BtnUnderline />\n <Separator />\n <BtnNumberedList />\n <BtnBulletList />\n <Separator />\n <BtnLink />\n <BtnClearFormatting />\n <Separator />\n <BtnStyles />\n </Toolbar>\n </Editor>\n );\n}\n"],"names":["extendStatics","d","b","Object","setPrototypeOf","__proto__","Array","p","hasOwnProperty","__extends","__","this","constructor","prototype","create","__assign","assign","t","s","i","n","arguments","length","call","apply","__rest","e","indexOf","getOwnPropertySymbols","isObject","item","isArray","normalizeHtml","str","replace","replaceCaret","el","target","findLastTextNode","node","nodeType","Node","TEXT_NODE","children","childNodes","textNode","isTargetFocused","document","activeElement","nodeValue","range","createRange","sel","window","getSelection","setStart","collapse","removeAllRanges","addRange","HTMLElement","focus","tslib_1.__extends","Component","ContentEditable","nextProps","props","value","innerHTML","a","keys","every","key","compare","previousValue","contentEditableRef","event","previous","onChange","_a","tagName","createElement","contentEditable","disabled","dangerouslySetInnerHTML","__html","onBlur","onInput","onKeyDown","onKeyUp","ref","setElementRef","_super","_this","bind","styles","button","normal","backgroundColor","border","color","height","outline","padding","verticalAlign","width","hovered","active","flex","dropdown","boxSizing","marginTop","editor","borderRadius","display","flexDirection","minHeight","separator","margin","EditorContext","createContext","defaultStyles","PureComponent","Editor","addEventListener","onClickOutside","removeEventListener","setState","contains","selection","onSelect","parentElement","rangeCount","getRangeAt","startContainer","parentNode","getSelectedNode","_b","allStyles","deepMerge","_i","sources","source","shift","context","React.createElement","style","Provider","setContentEditableRef","onTextSelect","state","withEditorContext","WithEditorContext","displayName","name","Consumer","BtnBold","createButton","BtnClearFormatting","BtnItalic","BtnLink","selected","nodeName","execCommand","prompt","BtnNumberedList","xmlns","viewBox","fill","BtnRedo","BtnUnderline","textDecoration","BtnUndo","BtnBulletList","Button","setHovered","inputProps","hoverStyle","onMouseEnter","onMouseLeave","title","content","command","ButtonFactory","buttonProps","queryCommandState","onMouseDown","items","BtnStyles","DropdownFactory","ddProps","Dropdown","parseInt","commandArgument","preventDefault","selectedIndex","hidden","map","index","WrappedSeparator","Toolbar","rootStyle","root","borderBottom","Separator"],"mappings":"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"}