React select inline options - react-select

I'm using react-select and I was wondering how I could use the optionRenderer to display my options inline. See the picture below:
#react-select

You can use JSX inside label option
const options = [
{
label: <div className="label-item">ORA</div>,
value="ORA"
}, ....
]
Then modify class of react-select to customize it (maybe use styled-components)
import 'styled' from 'styled-component'
import 'select' from 'react-select'
const StyleSelect = styled(select).`
.select {
.select-control { ... }
}
`
Just use StyleSelect like normal select

Related

show block toolbar programmatically gutenberg

I am creating a block with InnerBlocks component.
If no content added to the InnerBlocks (and even with content in fact) it is very difficult to popup the block toolbar
I would like to add an iconbutton on top corner that will show the block floating toolbar
How can I tell the .block-editor-block-contextual-toolbar to show?
I don't see any method of the .wp-block in the inspector that would do that and the documentation of Block Controls: Block Toolbar and Settings Sidebar https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/block-controls-toolbar-and-sidebar/ is quite basic
Many thanks
You can use useSelect() to determine if there are any blocks present in the InnerBlocks component:
import { useSelect } from '#wordpress/data';
const hasInnerBlocks = useSelect((select) => (
select('core/block-editor').getBlock(clientId).innerBlocks.length > 0
), [clientId]);
Then you can use hasInnerBlocks to conditionally render whatever you'd like within the edit function:
{ !!hasInnerBlocks && (
<BlockControls group="block">
<ToolbarGroup
// Toolbar group settings here
/>
</BlockControls>
) }
Try to use same code structure among the edit and save methods. The RIchText need to be waraped inside div.
<div>
<RichText.Content
className={ `sticky-note-${ props.attributes.alignment }` }
style={ {
fontSize: props.attributes.fontSize,backgroundColor: props.attributes.color,
} }
tagName="p"
value={ props.attributes.content }/>
</div>
Example
I created this example to illustrate your situation.
import { InnerBlocks, BlockControls } from '#wordpress/block-editor';
// ...
edit: () => {
const blockProps = {
// your own props
};
return (
<div { ...blockProps }>
<BlockControls>
// your controls
</BlockControls>
<InnerBlocks />
</div>
);
}
Problem
For the BlockControls to decide whether or not it should appear, it needs to get some context from its parent which your own props don't have.
Solution:
Use the block props instead for the parent of BlockControls.
Steps:
Import useBlockProps from #wordpress/block-editor:
import { InnerBlocks, BlockControls, useBlockProps } from '#wordpress/block-editor';
Pass your own props as an argument to useBlockProps():
const blockProps = useBlockProps({
// your own props
});
Result
import { InnerBlocks, BlockControls, useBlockProps } from '#wordpress/block-editor';
// ...
edit: () => {
const blockProps = useBlockProps({
// your own props
});
return (
<div { ...blockProps }>
<BlockControls>
// your controls
</BlockControls>
<InnerBlocks />
</div>
);
}
Links
I hope that helped.
My answer is based on Wordpress's official Block Editor Handbook:
https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/block-controls-toolbar-and-sidebar/#block-toolbar
https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/nested-blocks-inner-blocks/
https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/#block-wrapper-props

Change Ant Design Pro Table pagination language

I have already set the ProTable's language to en-US. Everything is translated to English already but the pagination footer still is in Chinese. How can I change the pagination language to English?
import ProTable, { ProColumns, IntlProvider, enUSIntl } from '#ant-design/pro-table';
const ProTableList: React.FC<{}> = () => {
return (
<IntlProvider value={enUSIntl}>
<ProTable<TableListItem>
headerTitle="Example List"
actionRef={actionRef}
rowKey="key"
...
/>
...
</IntlProvider>
)
}
If you use Ant Design with Pro Components than you need to use Internationalization from non pro version of Ant Design.
Wrap your App or in this case only ProTable component with ConfigProvider like in code below and you will get english translate.
import React from 'react';
import { ConfigProvider } from 'antd';
import enUS from 'antd/lib/locale/en_US';
import ProTable from '#ant-design/pro-table'
const YourComponent = () => {
return (
<ConfigProvider locale={enUS}>
<ProTable />
</ConfigProvider>
);
}
export default YourComponent;
I figured it out but forgot to update the answer here. The ProTable component has a showTotal method under pagination. You can use the provided total and range variables to modify the displayed pagination text.
import ProTable, { ProColumns, IntlProvider, enUSIntl } from '#ant-design/pro-table';
const ProTableList: React.FC<{}> = () => {
return (
<IntlProvider value={enUSIntl}>
<ProTable<TableListItem>
headerTitle="Example List"
actionRef={actionRef}
rowKey="key"
...
pagination={{
showTotal: (total, range) => (
<div>{`showing ${range[0]}-${range[1]} of ${total} total items`}</div>
),
}}
/>
...
</IntlProvider>
)
}
Will result in this:
Encountering the same issue, I think it's a bug. You can disable it by setting
showTotal to false
pagination={{ showTotal: false }}

How do I get toolbar available items in CKEDITOR 5?

I wanted to configure the toolbar in CKEDITOR 5. I took a look at the documentation.
https://ckeditor5.github.io/docs/nightly/ckeditor5/latest/builds/guides/integration/configuration.html
Yet, the only script related to my question is:
Array.from( editor.ui.componentFactory.names );
It is way too difficult for a frontend programmer to understand. Where do I put this script? How do I output the results? Is there a detailed tutorial?
Matter fact, it would be nice if CKEDITOR simply put the available items in the documentation. That will save a hell lot of troubles.
Thanks!
You can put this code right in the body of code samples which you can find e.g. in CKEditor 5 Build's Basic API guide. For example:
ClassicEditor
.create( document.querySelector( '#editor' ) )
.then( editor => {
console.log( Array.from( editor.ui.componentFactory.names() ) );
} )
.catch( error => {
console.error( error );
} );
As #Szymon Cofalik mentioned in his answer ā€“ there's no single list of buttons which are available in all builds. CKEditor 5 builds may differ not only visually ā€“ they may also contain different plugins and hence different buttons. So, using that code snippet is the safest and future-proof solution.
you can use console.log( Array.from( editor.ui.componentFactory.names() ) ); which will give you:
["undo", "redo", "bold", "italic", "blockQuote", "ckfinder", "imageTextAlternative", "imageUpload", "heading", "imageStyle:full", "imageStyle:side", "link", "numberedList", "bulletedList", "mediaEmbed", "insertTable", "tableColumn", "tableRow", "mergeTableCells"]
Example code you can use to list available toolbar
var editor = ClassicEditor
.create(document.querySelector('#editor'), {
toolbar: ['headings', 'bold', 'italic', 'link', 'bulletedList', 'numberedList'],
heading: {
options: [
{modelElement: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph'},
{modelElement: 'heading1', viewElement: 'h1', title: 'Heading 1', class: 'ck-heading_heading1'},
{modelElement: 'heading2', viewElement: 'h2', title: 'Heading 2', class: 'ck-heading_heading2'},
{modelElement: 'heading', viewElement: 'h3', title: 'Heading 3', class: 'ck-heading_heading3'}
]
}
})
.then(function (editor) {
console.log(Array.from(editor.ui.componentFactory.names()));
});
For anyone coming here wondering how to make use of the Array.from(editor.ui.componentFactory.names()) solution (as described in the other answers) in Angular (e.g. Angular 8), here is a description. If you try to do it in ngOnInit or ngAfterViewInit, it is too early and you will get something like Cannot read property 'ui' of null. You need to listen for the ready event from the ckeditor and query the names at that point as follows.
In your component template code, give the editor an id and listen for the ready event:
<ckeditor
#editor
[editor]="Editor"
[config]="config"
(ready)="onEditorReady($event)">
</ckeditor>
Then in your component typescript code, add a #ViewChild annotation and implement onEditorReady as follows:
#ViewChild('editor', {static: false})
editorComponent: CKEditorComponent;
onEditorReady(event: any): void {
const toolbarItems = Array.from(this.editorComponent.editorInstance.ui.componentFactory.names());
console.log('Available toolbar items: ' + toolbarItems.join(', '));
}
You will then see something like this in the console:
Available toolbar items: undo, redo, bold, italic, blockQuote,
ckfinder, imageTextAlternative, imageUpload, heading, imageStyle:full,
imageStyle:side, indent, outdent, link, numberedList, bulletedList,
mediaEmbed, insertTable, tableColumn, tableRow, mergeTableCells
It is difficult to keep plugin names in one place in documentation because:
There are multiple builds which differs,
New plugins are developed and added.
If you want to check what toolbar items are available in the build you are currently using, open developer's console in the browser you are using and execute the quoted line of code
Array.from( editor.ui.componentFactory.names );
Of course, editor has to be the editor instance.
I hope this answers your question.
EDIT: Creating editor is described in the documentation too. But you have to assign editor instance to editor variable.
For example:
ClassicEditor
.create( document.querySelector( '#editor' ) )
.then( editor => {
window.editor = editor;
// Or alternatively you could paste that line here and look at console.
} );
Adding to #DestinyB answer - perhaps a simpler solution for Vue - just listen for #ready="onReady" on the ckeditor component, and in the onReady method:
onReady(event) {
console.log(Array.from(event.ui.componentFactory.names()));
},
Adding to #user2846469 Response, It can be achieved in vue.js simply by the sample below;
import ClassicEditorfrom '#ckeditor/ckeditor5-build-classic';
export default {
data() {
return {
editor: ClassicEditor,
editorData: '',
editorConfig: {}
},
mounted() {
console.log(this.editor.builtinPlugins.map( plugin => plugin.pluginName ));
}
}
}
In React
import { CKEditor } from '#ckeditor/ckeditor5-react';
import ClassicEditor from '#ckeditor/ckeditor5-build-classic';
export default class AddArticle extends Component {
render() {
return <CKEditor config={EditorConfig} editor={ClassicEditor} onReady={(event) => {
console.log(Array.from(event.ui.componentFactory.names()))}} />
}
}

How to get css style's value from outside in react native?

I have a .js file which holds global data (actually i am going to fill it from website). Here it is:
const DynGlobals = {
HomePageColor: {
color: '#e74c3c'
}
}
/*
or i can set it like this
HomePageColor: '#e74c3c'
/*
export { DynGlobals }
I have a view and trying to set it's style from this file. So far i have tried many things to create another const and set it to view's style but didn't work
const bgColorStyle = {
backgroundColor: {DynGlobals.HomePageColor.color}
}
with or without bracelets it doesn't work. Any advices on this?

Dynamic es6 module import names [duplicate]

Is it possible to import something into a module providing a variable name while using ES6 import?
I.e. I want to import some module at a runtime depending on values provided in a config:
import something from './utils/' + variableName;
Note that Iā€™m using Node.js, but answers must take compatibility with ECMAScript modules into consideration.
Not with the import statement. import and export are defined in such a way that they are statically analyzable, so they cannot depend on runtime information.
You are looking for the loader API (polyfill), but I'm a bit unclear about the status of the specification:
System.import('./utils/' + variableName).then(function(m) {
console.log(m);
});
Whilst this is not actually a dynamic import (eg in my circumstance, all the files I'm importing below will be imported and bundled by webpack, not selected at runtime), a pattern I've been using which may assist in some circumstances is:
import Template1 from './Template1.js';
import Template2 from './Template2.js';
const templates = {
Template1,
Template2
};
export function getTemplate (name) {
return templates[name];
}
or alternatively:
// index.js
export { default as Template1 } from './Template1';
export { default as Template2 } from './Template2';
// OtherComponent.js
import * as templates from './index.js'
...
// handy to be able to fall back to a default!
return templates[name] || templates.Template1;
I don't think I can fall back to a default as easily with require(), which throws an error if I try to import a constructed template path that doesn't exist.
Good examples and comparisons between require and import can be found here: http://www.2ality.com/2014/09/es6-modules-final.html
Excellent documentation on re-exporting from #iainastacio:
http://exploringjs.com/es6/ch_modules.html#sec_all-exporting-styles
I'm interested to hear feedback on this approach :)
There is a new specification which is called a dynamic import for ES modules.
Basically, you just call import('./path/file.js') and you're good to go. The function returns a promise, which resolves with the module if the import was successful.
async function importModule() {
try {
const module = await import('./path/module.js');
} catch (error) {
console.error('import failed');
}
}
Use cases
Use-cases include route based component importing for React, Vue etc and the ability to lazy load modules, once they are required during runtime.
Further Information
Here's is an explanation on Google Developers.
Browser compatibility (April 2020)
According to MDN it is supported by every current major browser (except IE) and caniuse.com shows 87% support across the global market share. Again no support in IE or non-chromium Edge.
In addition to Felix's answer, I'll note explicitly that this is not currently allowed by the ECMAScript 6 grammar:
ImportDeclaration :
import ImportClause FromClause ;
import ModuleSpecifier ;
FromClause :
from ModuleSpecifier
ModuleSpecifier :
StringLiteral
A ModuleSpecifier can only be a StringLiteral, not any other kind of expression like an AdditiveExpression.
I understand the question specifically asked for ES6 import in Node.js, but the following might help others looking for a more generic solution:
let variableName = "es5.js";
const something = require(`./utils/${variableName}`);
Note if you're importing an ES6 module and need to access the default export, you will need to use one of the following:
let variableName = "es6.js";
// Assigning
const defaultMethod = require(`./utils/${variableName}`).default;
// Accessing
const something = require(`./utils/${variableName}`);
something.default();
You can also use destructuring with this approach which may add more syntax familiarity with your other imports:
// Destructuring
const { someMethod } = require(`./utils/${variableName}`);
someMethod();
Unfortunately, if you want to access default as well as destructuring, you will need to perform this in multiple steps:
// ES6 Syntax
Import defaultMethod, { someMethod } from "const-path.js";
// Destructuring + default assignment
const something = require(`./utils/${variableName}`);
const defaultMethod = something.default;
const { someMethod, someOtherMethod } = something;
you can use the non-ES6 notation to do that. this is what worked for me:
let myModule = null;
if (needsToLoadModule) {
myModule = require('my-module').default;
}
I had similar problem using Vue.js: When you use variable in import(variableName) at build time Webpack doesn't know where to looking for. So you have to restrict it to known path with propriate extension like that:
let something = import("#/" + variableName + ".js")
That answer in github for the same issue was very helpful for me.
I less like this syntax, but it work:
instead of writing
import memberName from "path" + "fileName";
// this will not work!, since "path" + "fileName" need to be string literal
use this syntax:
let memberName = require("path" + "fileName");
Dynamic import() (available in Chrome 63+) will do your job. Here's how:
let variableName = 'test.js';
let utilsPath = './utils/' + variableName;
import(utilsPath).then((module) => { module.something(); });
./utils/test.js
export default () => {
doSomething...
}
call from file
const variableName = 'test';
const package = require(`./utils/${variableName}`);
package.default();
I would do it like this
function load(filePath) {
return () => System.import(`${filePath}.js`);
// Note: Change .js to your file extension
}
let A = load('./utils/' + variableName)
// Now you can use A in your module
It depends. You can use template literals in dynamic imports to import a file based on a variable.
I used dynamic imports to add .vue files to vue router. I have excluded the Home.vue view import.
const pages = [
'About',
['About', 'Team'],
]
const nodes = [
{
name: 'Home',
path: '/',
component: Home,
}
]
for (const page of pages) {
if (typeof page === 'string') {
nodes.push({
name: page,
path: `/${page}`,
component: import(`./views/${page}.vue`),
})
} else {
nodes.push({
name: _.last(page),
path: `/${page.join('/')}`,
component: import(`./views/${_.last(page)}.vue`)
})
}
}
This worked for me. I was using yarn + vite + vue on replit.