mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-07-09 20:36:32 +00:00
generalized the react-select
component
so tha we can reuse it all over the application. Signed-off-by: Akos Kitta <kittaakos@typefox.io>
This commit is contained in:
parent
a866bde4d1
commit
4129544738
@ -0,0 +1,66 @@
|
||||
import * as React from 'react';
|
||||
import Select from 'react-select';
|
||||
import { Styles } from 'react-select/src/styles';
|
||||
import { Props } from 'react-select/src/components';
|
||||
import { ThemeConfig } from 'react-select/src/theme';
|
||||
|
||||
export class ArduinoSelect<T> extends Select<T> {
|
||||
|
||||
constructor(props: Readonly<Props<T>>) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render(): React.ReactNode {
|
||||
const { defaultValue, onChange, options, className } = this.props;
|
||||
const height = 25;
|
||||
const styles: Styles = {
|
||||
control: styles => ({
|
||||
...styles,
|
||||
width: 200,
|
||||
color: 'var(--theia-ui-font-color1)'
|
||||
}),
|
||||
dropdownIndicator: styles => ({
|
||||
...styles,
|
||||
padding: 0
|
||||
}),
|
||||
indicatorSeparator: () => ({
|
||||
display: 'none'
|
||||
}),
|
||||
indicatorsContainer: () => ({
|
||||
padding: '0px 5px'
|
||||
}),
|
||||
menu: styles => ({
|
||||
...styles,
|
||||
marginTop: 0
|
||||
})
|
||||
};
|
||||
const theme: ThemeConfig = theme => ({
|
||||
...theme,
|
||||
borderRadius: 0,
|
||||
spacing: {
|
||||
controlHeight: height,
|
||||
baseUnit: 2,
|
||||
menuGutter: 4
|
||||
}, colors: {
|
||||
...theme.colors,
|
||||
// `primary50`??? it's crazy but apparently, without this, we would get a light-blueish
|
||||
// color when selecting an option in the select by clicking and then not releasing the button.
|
||||
// https://react-select.com/styles#overriding-the-theme
|
||||
primary50: 'var(--theia-accent-color4)',
|
||||
}
|
||||
});
|
||||
const DropdownIndicator = () => <span className='fa fa-caret-down caret' />;
|
||||
return <Select
|
||||
options={options}
|
||||
defaultValue={defaultValue}
|
||||
onChange={onChange}
|
||||
components={{ DropdownIndicator }}
|
||||
theme={theme}
|
||||
styles={styles}
|
||||
classNamePrefix='arduino-select'
|
||||
className={className}
|
||||
isSearchable={false}
|
||||
/>
|
||||
}
|
||||
|
||||
}
|
Before Width: | Height: | Size: 962 B After Width: | Height: | Size: 962 B |
@ -1,10 +1,8 @@
|
||||
import * as React from 'react';
|
||||
import * as dateFormat from 'dateformat';
|
||||
import { postConstruct, injectable, inject } from 'inversify';
|
||||
import { ThemeConfig } from 'react-select/src/theme';
|
||||
import { OptionsType } from 'react-select/src/types';
|
||||
import Select from 'react-select';
|
||||
import { Styles } from 'react-select/src/styles';
|
||||
import { ArduinoSelect } from '../components/arduino-select';
|
||||
import { ReactWidget, Message, Widget } from '@theia/core/lib/browser/widgets';
|
||||
import { MonitorConfig } from '../../common/protocol/monitor-service';
|
||||
import { MonitorModel } from './monitor-model';
|
||||
@ -74,11 +72,6 @@ export class MonitorWidget extends ReactWidget {
|
||||
this.update();
|
||||
}
|
||||
|
||||
onBeforeAttach(msg: Message): void {
|
||||
super.onBeforeAttach(msg);
|
||||
this.clearConsole();
|
||||
}
|
||||
|
||||
protected onAfterAttach(msg: Message): void {
|
||||
super.onAfterAttach(msg);
|
||||
this.monitorConnection.autoConnect = true;
|
||||
@ -131,8 +124,8 @@ export class MonitorWidget extends ReactWidget {
|
||||
<SerialMonitorSendField onSend={this.onSend} />
|
||||
</div>
|
||||
<div className='config'>
|
||||
{this.renderSelectField('arduino-serial-monitor-line-endings', lineEndings, lineEnding, this.onChangeLineEnding)}
|
||||
{this.renderSelectField('arduino-serial-monitor-baud-rates', baudRates, baudRate, this.onChangeBaudRate)}
|
||||
<ArduinoSelect className='serial-monitor-select' options={lineEndings} defaultValue={lineEnding} onChange={this.onChangeLineEnding} />
|
||||
<ArduinoSelect className='serial-monitor-select' options={baudRates} defaultValue={baudRate} onChange={this.onChangeBaudRate} />
|
||||
</div>
|
||||
</div>
|
||||
<div id='serial-monitor-output-container'>
|
||||
@ -155,67 +148,8 @@ export class MonitorWidget extends ReactWidget {
|
||||
this.model.baudRate = option.value;
|
||||
}
|
||||
|
||||
protected renderSelectField<T>(
|
||||
id: string,
|
||||
options: OptionsType<SelectOption<T>>,
|
||||
defaultValue: SelectOption<T>,
|
||||
onChange: (option: SelectOption<T>) => void): React.ReactNode {
|
||||
|
||||
const height = 25;
|
||||
const styles: Styles = {
|
||||
control: (styles, state) => ({
|
||||
...styles,
|
||||
width: 200,
|
||||
color: 'var(--theia-ui-font-color1)'
|
||||
}),
|
||||
dropdownIndicator: styles => ({
|
||||
...styles,
|
||||
padding: 0
|
||||
}),
|
||||
indicatorSeparator: () => ({
|
||||
display: 'none'
|
||||
}),
|
||||
indicatorsContainer: () => ({
|
||||
padding: '0px 5px'
|
||||
}),
|
||||
menu: styles => ({
|
||||
...styles,
|
||||
marginTop: 0
|
||||
})
|
||||
};
|
||||
const theme: ThemeConfig = theme => ({
|
||||
...theme,
|
||||
borderRadius: 0,
|
||||
spacing: {
|
||||
controlHeight: height,
|
||||
baseUnit: 2,
|
||||
menuGutter: 4
|
||||
}, colors: {
|
||||
...theme.colors,
|
||||
// `primary50`??? it's crazy but apparently, without this, we would get a light-blueish
|
||||
// color when selecting an option in the select by clicking and then not releasing the button.
|
||||
// https://react-select.com/styles#overriding-the-theme
|
||||
primary50: 'var(--theia-accent-color4)',
|
||||
}
|
||||
});
|
||||
const DropdownIndicator = () => <span className='fa fa-caret-down caret' />;
|
||||
return <Select
|
||||
options={options}
|
||||
defaultValue={defaultValue}
|
||||
onChange={onChange}
|
||||
components={{ DropdownIndicator }}
|
||||
theme={theme}
|
||||
styles={styles}
|
||||
maxMenuHeight={this.widgetHeight - 40}
|
||||
classNamePrefix='sms'
|
||||
className='serial-monitor-select'
|
||||
id={id}
|
||||
isSearchable={false}
|
||||
/>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export namespace SerialMonitorSendField {
|
||||
export interface Props {
|
||||
readonly onSend: (text: string) => void
|
||||
@ -248,14 +182,12 @@ export class SerialMonitorSendField extends React.Component<SerialMonitorSendFie
|
||||
<input
|
||||
tabIndex={-1}
|
||||
ref={ref => this.inputField = ref}
|
||||
type='text' id='serial-monitor-send'
|
||||
id='serial-monitor-send'
|
||||
type='text'
|
||||
autoComplete='off'
|
||||
value={this.state.value}
|
||||
onChange={this.handleChange} />
|
||||
<button className='button' onClick={this.handleSubmit}>Send</button>
|
||||
{/* <input className='btn' type='submit' value='Submit' />
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
</form> */}
|
||||
</React.Fragment>
|
||||
}
|
||||
|
||||
@ -268,6 +200,7 @@ export class SerialMonitorSendField extends React.Component<SerialMonitorSendFie
|
||||
this.setState({ value: '' });
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export namespace SerialMonitorOutput {
|
||||
@ -279,6 +212,9 @@ export namespace SerialMonitorOutput {
|
||||
|
||||
export class SerialMonitorOutput extends React.Component<SerialMonitorOutput.Props> {
|
||||
|
||||
/**
|
||||
* Do not touch it. It is used to be able to "follow" the serial monitor log.
|
||||
*/
|
||||
protected anchor: HTMLElement | null;
|
||||
|
||||
render() {
|
||||
|
46
arduino-ide-extension/src/browser/style/arduino-select.css
Normal file
46
arduino-ide-extension/src/browser/style/arduino-select.css
Normal file
@ -0,0 +1,46 @@
|
||||
.arduino-select__control {
|
||||
border: var(--theia-layout-color2) var(--theia-border-width) solid !important;
|
||||
background: var(--theia-layout-color2) !important;
|
||||
}
|
||||
|
||||
.arduino-select__control:hover {
|
||||
border: var(--theia-layout-color2) var(--theia-border-width) solid !important;
|
||||
}
|
||||
|
||||
.arduino-select__control--is-focused {
|
||||
border-color: var(--theia-accent-color3) !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.arduino-select__option--is-selected {
|
||||
background-color: var(--theia-accent-color3) !important;
|
||||
color: var(--theia-content-font-color0) !important;
|
||||
border-color: var(--theia-accent-color3) !important;
|
||||
}
|
||||
|
||||
.arduino-select__option--is-focused {
|
||||
background-color: var(--theia-accent-color4) !important;
|
||||
border-color: var(--theia-accent-color3) !important;
|
||||
}
|
||||
|
||||
.arduino-select__menu {
|
||||
background-color: var(--theia-layout-color2) !important;
|
||||
border: 1px solid var(--theia-accent-color3) !important;
|
||||
top: auto !important; /* to align the top of the menu with the bottom of the control */
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.arduino-select__control.arduino-select__control--menu-is-open {
|
||||
border: 1px solid !important;
|
||||
border-color: var(--theia-accent-color3) !important;
|
||||
border-bottom-color: var(--theia-layout-color2) !important; /* if the bottom border color has the same color as the background of the control, we make the border "invisible" */
|
||||
}
|
||||
|
||||
.arduino-select__value-container .arduino-select__single-value {
|
||||
color: var(--theia-ui-font-color1) !important;
|
||||
}
|
||||
|
||||
.arduino-select__menu-list {
|
||||
padding-top: 0 !important;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
@ -2,4 +2,5 @@
|
||||
@import './board-select-dialog.css';
|
||||
@import './main.css';
|
||||
@import './editor.css';
|
||||
@import './monitor.css';
|
||||
@import './monitor.css';
|
||||
@import './arduino-select.css';
|
||||
|
@ -1,6 +1,6 @@
|
||||
.library-tab-icon {
|
||||
-webkit-mask: url('library-tab-icon.svg');
|
||||
mask: url('library-tab-icon.svg');
|
||||
-webkit-mask: url('../icons/library-tab-icon.svg');
|
||||
mask: url('../icons/library-tab-icon.svg');
|
||||
}
|
||||
|
||||
.arduino-list-widget {
|
||||
|
@ -78,51 +78,3 @@
|
||||
.p-TabBar-toolbar .item .clear-all {
|
||||
background: var(--theia-icon-clear) no-repeat;
|
||||
}
|
||||
|
||||
/* React Select Styles */
|
||||
.serial-monitor-select .sms__control {
|
||||
border: var(--theia-layout-color2) var(--theia-border-width) solid;
|
||||
background: var(--theia-layout-color2);
|
||||
}
|
||||
|
||||
.serial-monitor-select .sms__control:hover {
|
||||
border: var(--theia-layout-color2) var(--theia-border-width) solid !important;
|
||||
}
|
||||
|
||||
.serial-monitor-select .sms__control--is-focused {
|
||||
border-color: var(--theia-accent-color3) !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.serial-monitor-select .sms__option--is-selected {
|
||||
background-color: var(--theia-accent-color3);
|
||||
color: var(--theia-content-font-color0);
|
||||
border-color: var(--theia-accent-color3);
|
||||
}
|
||||
|
||||
.serial-monitor-select .sms__option--is-focused {
|
||||
background-color: var(--theia-accent-color4);
|
||||
border-color: var(--theia-accent-color3);
|
||||
}
|
||||
|
||||
.serial-monitor-select .sms__menu {
|
||||
background-color: var(--theia-layout-color2);
|
||||
border: 1px solid var(--theia-accent-color3);
|
||||
top: auto !important; /* to align the top of the menu with the bottom of the control */
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.serial-monitor-select .sms__control.sms__control--menu-is-open {
|
||||
border: 1px solid;
|
||||
border-color: var(--theia-accent-color3) !important;
|
||||
border-bottom-color: var(--theia-layout-color2) !important; /* if the bottom border color has the same color as the background of the control, we make the border "invisible" */
|
||||
}
|
||||
|
||||
.serial-monitor-select .sms__value-container .sms__single-value {
|
||||
color: var(--theia-ui-font-color1);
|
||||
}
|
||||
|
||||
.sms__menu-list {
|
||||
padding-top: 0 !important;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user