React Draft Wysiwyg apply bold, italic or udenderlina to whole content - reactjs

I need to apply the Bold, Italic, Underline style to the whole content of editor, without selected text, like the align styles but I couldn't find the way for that. Is the possible to change the action or handler?

Yes, it is possible. You could update your SelectionState at the moment where your applying style.
Here, we selecting all text
const selection = editorState.getSelection().merge({
anchorKey: currentContent.getFirstBlock().getKey(),
anchorOffset: 0,
focusOffset: currentContent.getLastBlock().getText().length,
focusKey: currentContent.getLastBlock().getKey()
});
Then, we applying new selection
const editorStateWithAllSelection = EditorState.acceptSelection(
editorState,
selection
);
const newState = RichUtils.toggleInlineStyle(
editorStateWithAllSelection,
inlineStyle
)
if you want to avoid your text to be selected in the end result, we could apply our old selection
const selectionBefore = editorState.getSelection();
// updating selection, toggling style ...
const editorStateWithSelectionBefore = EditorState.acceptSelection(
newState,
selectionBefore
);
setEditorState(editorStateWithSelectionBefore);
Example on Codeandbox

Related

Get usual spacing for menu and toolbar in Qooxdoo

Doing a simple setup with a Qooxdoo menu bar and tool bar I get an unexpected layout.
Running this snippet in the Qooxdoo playground:
const layout = new qx.ui.layout.VBox(5);
const container = new qx.ui.container.Composite(layout);
const menubar = new qx.ui.menubar.MenuBar();
const menu = new qx.ui.menu.Menu();
menubar.add(new qx.ui.menubar.Button('File'), null, menu);
const toolbar = new qx.ui.toolbar.ToolBar();
toolbar.add(new qx.ui.toolbar.Button('test'));
container.add(menubar,{flex:0});
container.add(toolbar,{flex:0});
const windowManager = new qx.ui.window.Manager();
const desktop = new qx.ui.window.Desktop(windowManager);
desktop.setBackgroundColor('#a0f0f0');
container.add(desktop,{flex:1});
this.getRoot().add(container, {edge: 0});
I get this result:
How can I get rid of the white separators and also remove most of the grey padding in the toolbar?
The final result should look like a usual desktop application.
In your VBox layout you set 5px what means spacing between children. Pass 0 to get rid of it. Also setPadding(0,0,0,0) for both toolbar and menubar to reduce "grey" padding. For buttons of toolbar setMargin(0,0,0,0) to get rid of margin of buttons.

How to save state of column visibility in material ui data grid

I have a fairly simple datagrid table with the option to hide/show specific columns.
I want to save the state of the columns when a rerender occurs (in my case when the language is changed).
Here is a stripped down sample. Just hide a column and then click the button. The column-header change as expected but the hidden column reappears.
https://codesandbox.io/s/material-demo-forked-lq22m
I think I have to set the hide property correctly to the current state of the columns in my click handler:
const handleButtonClick = () => {
setColumnState((c) => c.map((d) => ({ ...d, hide:currentStateofHideForEachCol, headerName: "nombre" })));
};
But I cant find a way to access it.
Currently, by updating columnState you are forcing a rerender of a new grid instead of updating the current one, thus losing the state.
I changed your code behavior so it now uses GridColDef.renderHeader and React.useContext to change the column names based on the language without losing the grid's state.
In terms of saving the state of the grid, the whole state of the grid is not controllable, making it difficult to do so, particularly the columns' visibility is not accessible. However, other props (the sort, filter, and selection models) can be controlled. For example, you can control the page prop:
// This mimics the default page change behavior
const [currentPage, setCurrentPage] = useState(1);
const handleChangePage = useCallback(
(gridPageChangeParams)=> setCurrentPage(gridPageChangeParams.page),
[]
);
<DataGrid page ={currentPage} onPageChange={handleChangePage}

How to trigger onchange only when the content changes in draft js editor?

The onchange method in draft js is executed by the Editor when edits and selection changes occur. But I want to call trigger onchange only when the user is writing or the content changes and not on focus or selection. Is there any way I can compare the previous and current editor state?
You cannot do exactly that because draft-js keep selection state of your mouse inside the editor state, onChange must be triggered, and you must update the editor state, but you check for the old and new editor state plain text and know for sure if some characters are added or deleted
const [editorState,setEditorState]= useState(EditorState.createEmpty());
function onChange(newEditorState: EditorState) {
const currentPlainText = editorState.getCurrentContent().getPlainText();
const newPlainText = newEditorState.getCurrentContent().getPlainText();
setEditorState(newEditorState);
if (currentPlainText.trim() !== newPlainText.trim()) {
/**
* do what you want knowing that you have different content in the editor
*/
}
}
I use undoStack.size property to detect the content change. It works great.
https://draftjs.org/docs/api-reference-editor-state/#undostack
onEditorStateChange = (editorState) => {
const changed = !!editorState.getUndoStack().size
...
}

How to automatically resize AutoComplete field in Material UI?

I want to implement an AutoComplete field using Material UI, where the size of the field resizes according to the option selected.
When the option selected does not occupy the entire field, I would like the size of the field to reduce. And if the option selected is longer than what the field can accommodate, I would like the field size to increase to display the entire option
How can this be implemented in Material UI?
The input width can be changed by creating a State variable.
const [inputWidth, setInputWidth] = useState(DEFAULT_INPUT_WIDTH);
where
const DEFAULT_INPUT_WIDTH = 90;
can be set to any default value. Ex: 90
In addition, create a const for the font size
const FONT_SIZE = 9;
The Props taken by autocomplete take a width value for the TextField. Set the width of the field in the style attribute.
let autocompleteInputProps = {
label: 'ABC',
style: { width: `${inputWidth}px`},
};
Whichever function that handles the select change will include the following code
const handleSelectChange = (value) => {
if (value.code.toString().length !== 1){
setInputWidth(DEFAULT_INPUT_WIDTH + value.toString().length * FONT_SIZE)
} else {
setInputWidth(DEFAULT_INPUT_WIDTH)
}
};
This explains the same in TextField.

draft.js: how to preserve paragraph breaks when pasting content?

Is there documentation that explains how to preserve paragraph breaks when content is pasted into draft.js? Other formating looks reasonable but all the paragraph blocks are collapsed into a single paragraph block when pasting.
You can handle this using a prop for Editor.
handlePastedText = (text: string, html?: string, editorState: EditorState) => {
const selection = editorState.getSelection();
const pastedBlocks = ContentState.createFromText(text).blockMap;
const newState = Modifier.replaceWithFragment(
editorState.getCurrentContent(),
editorState.getSelection(),
pastedBlocks,
);
const newEditorState = EditorState.push(editorState, newState, "insert-fragment");
this.handleChange(newEditorState);
return "handled";
};
And then pass this as props in Editor. This will solve your problem.
Unfortunately, there is no public documentation of processing of pasted content. But since draft-js is open-sourced, reading the sources comes to the rescue.
Draft-js 0.9.1 and below
Just specify p as aliased element for unstyled block using blockRenderMap:
import { Map } from 'immutable';
import Editor from 'draft-js';
const customRenderMap = Map({
unstyled: {
element: 'div',
// will be used in convertFromHTMLtoContentBlocks
aliasedElements: ['p'],
},
});
<Editor
editorState={this.state.editorState}
blockRenderMap={customRenderMap}
/>
Explanation:
When you paste content to draft-js, editOnPaste function gets invoked. Inside it draft determines that content you pasted is html (yes, when you copy-paste any text from text processors like MS Word, Google Docs or Apple Pages, it's actually html), and calls convertFromHTMLToContentBlocks().
convertFromHTMLToContentBlocks() in its turn uses blockRenderMap to determine how to split html to blocks.
Draft-js 0.10.0
div is aliased with p by default in draft-js#0.10.0

Resources