1
0
mirror of https://github.com/flarum/core.git synced 2025-07-27 19:50:20 +02:00
Files
php-flarum/js/forum/src/components/TextEditor.js
2017-11-05 16:25:34 +10:30

166 lines
3.6 KiB
JavaScript

import Component from 'flarum/Component';
import ItemList from 'flarum/utils/ItemList';
import listItems from 'flarum/helpers/listItems';
import Button from 'flarum/components/Button';
/**
* The `TextEditor` component displays a textarea with controls, including a
* submit button.
*
* ### Props
*
* - `submitLabel`
* - `value`
* - `placeholder`
* - `disabled`
*/
export default class TextEditor extends Component {
init() {
/**
* The value of the textarea.
*
* @type {String}
*/
this.value = m.prop(this.props.value || '');
}
view() {
return (
<div className="TextEditor">
<textarea className="FormControl Composer-flexible"
config={this.configTextarea.bind(this)}
oninput={m.withAttr('value', this.oninput.bind(this))}
placeholder={this.props.placeholder || ''}
disabled={!!this.props.disabled}
value={this.value()}/>
<ul className="TextEditor-controls Composer-footer">
{listItems(this.controlItems().toArray())}
</ul>
</div>
);
}
/**
* Configure the textarea element.
*
* @param {DOMElement} element
* @param {Boolean} isInitialized
*/
configTextarea(element, isInitialized) {
if (isInitialized) return;
const handler = () => {
this.onsubmit();
m.redraw();
};
$(element).bind('keydown', 'meta+return', handler);
$(element).bind('keydown', 'ctrl+return', handler);
}
/**
* Build an item list for the text editor controls.
*
* @return {ItemList}
*/
controlItems() {
const items = new ItemList();
items.add('submit',
Button.component({
children: this.props.submitLabel,
icon: 'check',
className: 'Button Button--primary',
itemClassName: 'App-primaryControl',
onclick: this.onsubmit.bind(this)
})
);
if (this.props.preview) {
items.add('preview',
Button.component({
icon: 'eye',
className: 'Button Button--icon',
onclick: this.props.preview,
title: app.translator.trans('core.forum.composer.preview_tooltip')
})
);
}
return items;
}
/**
* Set the value of the text editor.
*
* @param {String} value
*/
setValue(value) {
this.$('textarea').val(value).trigger('input');
}
/**
* Set the selected range of the textarea.
*
* @param {Integer} start
* @param {Integer} end
*/
setSelectionRange(start, end) {
const $textarea = this.$('textarea');
$textarea[0].setSelectionRange(start, end);
$textarea.focus();
}
/**
* Get the selected range of the textarea.
*
* @return {Array}
*/
getSelectionRange() {
const $textarea = this.$('textarea');
return [$textarea[0].selectionStart, $textarea[0].selectionEnd];
}
/**
* Insert content into the textarea at the position of the cursor.
*
* @param {String} insert
*/
insertAtCursor(insert) {
const textarea = this.$('textarea')[0];
const value = this.value();
const index = textarea ? textarea.selectionStart : value.length;
this.setValue(value.slice(0, index) + insert + value.slice(index));
// Move the textarea cursor to the end of the content we just inserted.
if (textarea) {
const pos = index + insert.length;
this.setSelectionRange(pos, pos);
}
}
/**
* Handle input into the textarea.
*
* @param {String} value
*/
oninput(value) {
this.value(value);
this.props.onchange(this.value());
m.redraw.strategy('none');
}
/**
* Handle the submit button being clicked.
*/
onsubmit() {
this.props.onsubmit(this.value());
}
}