Skip to content

Commit

Permalink
Added textarea widget (#442)
Browse files Browse the repository at this point in the history
* Add maxLength for text widget

* Add missing support of disabled list items in AntD

* defaultTextWidth, defaultSliderWidth

* .

* Flex used to fullWidth

* fix css

* fullWidth (for textarea)

* .

* removed defaultTextWidth

* Added textarea widget, with maxRows option

* doc

* 4.2.0
  • Loading branch information
ukrbublik authored Jun 24, 2021
1 parent d7b572f commit b3dc1ba
Show file tree
Hide file tree
Showing 28 changed files with 278 additions and 34 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Changelog
- 4.2.0
- Added `textarea` widget
- 4.1.1
- Fix warning about showSearch in MUI theme
- Fix incorrect override of vanilla button label (issue #347)
Expand Down
9 changes: 7 additions & 2 deletions CONFIG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ const {
},
widgets: {
text,
textarea,
number,
slider,
rangeslider, // missing in `BasicConfig`
Expand Down Expand Up @@ -186,7 +187,8 @@ Example:
|tooltip | | |Optional tooltip to be displayed in field list by hovering on item
|fieldSettings | | |Settings for widgets, will be passed as props. Example: `{min: 1, max: 10}` +
Available settings for Number and Slider widgets: `min`, `max`, `step`. Slider also supports `marks` (example: `{ 0: "0%", 100: "100%" }`). +
Available settings for date/time widgets: `timeFormat`, `dateFormat`, `valueFormat`, `use12Hours`, `useKeyboard`.
Available settings for date/time widgets: `timeFormat`, `dateFormat`, `valueFormat`, `use12Hours`, `useKeyboard`. +
Available settings for text widget: `maxLength`, `maxRows`.
|fieldSettings.listValues |+ for (multi)select, tree (multi)select | |List of values for (multi)select widget. +
Example for select/multiselect: `[{value: 'yellow', title: 'Yellow'}, {value: 'green', title: 'Green'}]`
(or alternatively `{ yellow: 'Yellow', green: 'Green' }`) +
Expand Down Expand Up @@ -329,6 +331,7 @@ Render settings:
|renderAfterWidget| |
|renderBeforeActions| |
|renderAfterActions| |
|defaultSliderWidth|"200px" |Width for slider
|===

Other settings:
Expand Down Expand Up @@ -552,6 +555,8 @@ const {
`(mixed val, Object fieldDef, Object wgtDef, string op, Object opDef) => any`
|valueLabel | |`config.settings.valueLabel` |Common option, text to be placed on top of widget if `config.settings.showLabels` is true
|valuePlaceholder | |`config.settings.valuePlaceholder` |Common option, placeholder text to be shown in widget for empty value
|maxLength | | |Option for `<TextWidget>`, `<TextAreaWidget>`
|maxRows | | |Option for `<TextAreaWidget>`
|timeFormat | |`HH:mm:ss` |Option for `<TimeWidget>`, `<DateTimeWidget>` to display time in widget. Example: `'HH:mm'`
|use12Hours | |`false` |Option for `<TimeWidget>`
|useKeyboard | |`true` |Option for Material-UI date/time pickers, `false` disables input with keyboard, only picker use is allowed
Expand Down Expand Up @@ -609,7 +614,7 @@ To enable this feature set `valueSources` of type to `['value', 'func']` (see be
|valueSources | |keys of `valueSourcesInfo` at link:#configsettings[config.settings] |Array with values `'value'`, `'field'`, `'func'`. If `'value'` is included, you can compare field with values. If `'field'` is included, you can compare field with another field of same type. If `'func'` is included, you can compare field with result of function (see link:#configfuncs[config.funcs]).
|defaultOperator | | |If specified, it will be auto selected when user selects field
|widgets.* |+ | |Available widgets for current type and their config. +
Normally there is only 1 widget per type. But see type `number` at https://github.com/ukrbublik/react-awesome-query-builder/tree/master/examples/demo/config.tsx[`examples/demo`] - it has 3 widhets `number`, `slider`, `rangeslider`. +
Normally there is only 1 widget per type. But see type `number` at https://github.com/ukrbublik/react-awesome-query-builder/tree/master/examples/demo/config.tsx[`examples/demo`] - it has 3 widgets `number`, `slider`, `rangeslider`. +
Or see type `select` - it has widget `select` for operator `=` and widget `multiselect` for operator `IN`.
|widgets.<widget>.operators | | |List of operators for widget, described in link:#configoperators[config.operators]
|widgets.<widget>.widgetProps | | |Can be used to override config of corresponding widget specified in link:#configwidgets[config.widgets]. Example: `{timeFormat: 'h:mm:ss A'}` for time field with AM/PM.
Expand Down
33 changes: 33 additions & 0 deletions css/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ ul.ant-select-selection__rendered {
margin-left: auto;
display: flex;
align-items: center;
padding-left: 10px;
}

.rule--drag-handler {
Expand Down Expand Up @@ -607,3 +608,35 @@ $rule_actions: ".widget--valuesrc", ".rule--drag-handler", ".rule--header";
margin-top: 10px;
margin-bottom: 10px;
}


/******************************************************************************/
/** Shrink textarea ***********************************************************/
/******************************************************************************/

.rule--body.can--shrink--value {
display: flex;
align-items: center;
.rule--value {
flex: 1;
}
.rule--value > .rule--widget {
display: flex;
.widget--widget {
flex: 1;
}
}
.rule--value > .rule--widget > .widget--valuesrc {
display: flex;
align-items: center;
}
}

.rule--value > .rule--widget > .widget--valuesrc {
.anticon {
height: 100%;
svg {
height: 100%;
}
}
}
26 changes: 17 additions & 9 deletions examples/demo/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,17 @@ export default (skin: string) => {
...InitialConfig.widgets,
// examples of overriding
text: {
...InitialConfig.widgets.text,
...InitialConfig.widgets.text
},
textarea: {
...InitialConfig.widgets.textarea,
maxRows: 3
},
slider: {
...InitialConfig.widgets.slider,
customProps: {
width: "300px"
}
...InitialConfig.widgets.slider
},
rangeslider: {
...InitialConfig.widgets.rangeslider,
customProps: {
width: "300px"
},
...InitialConfig.widgets.rangeslider
},
date: {
...InitialConfig.widgets.date,
Expand Down Expand Up @@ -185,6 +183,8 @@ export default (skin: string) => {
...InitialConfig.settings,
...localeSettings,

defaultSliderWidth: "200px",

valueSourcesInfo: {
value: {
label: "Value"
Expand Down Expand Up @@ -249,6 +249,14 @@ export default (skin: string) => {
}
}
},
bio: {
label: "Bio",
type: "text",
preferWidgets: ["textarea"],
fieldSettings: {
maxLength: 1000,
}
},
results: {
label: "Results",
type: "!group",
Expand Down
3 changes: 1 addition & 2 deletions examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,5 @@
"dependencies": {
"react-awesome-query-builder": "file:.."
},
"devDependencies": {
}
"devDependencies": {}
}
9 changes: 7 additions & 2 deletions modules/components/item/Rule.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {getFieldConfig, getOperatorConfig, getFieldWidgetConfig} from "../../uti
import {getFieldPathLabels} from "../../utils/ruleUtils";
import {useOnPropsChanged} from "../../utils/reactUtils";
import {Col, DragIcon, dummyFn, ConfirmFn} from "../utils";
const classNames = require("classnames");


@RuleContainer
Expand Down Expand Up @@ -248,6 +249,10 @@ class Rule extends PureComponent {
}

render () {
const { showOperatorOptions, selectedFieldWidgetConfig } = this.meta;
const { valueSrc, value } = this.props;
const canShrinkValue = valueSrc.first() == 'value' && !showOperatorOptions && value.size == 1 && selectedFieldWidgetConfig.fullWidth;

const parts = [
this.renderField(),
this.renderOperator(),
Expand All @@ -256,12 +261,12 @@ class Rule extends PureComponent {
this.renderAfterWidget(),
this.renderOperatorOptions(),
];
const body = <div key="rule-body" className="rule--body">{parts}</div>;
const body = <div key="rule-body" className={classNames("rule--body", canShrinkValue && "can--shrink--value")}>{parts}</div>;

const error = this.renderError();
const drag = this.renderDrag();
const del = this.renderDel();

return (
<>
{drag}
Expand Down
3 changes: 2 additions & 1 deletion modules/components/widgets/antd/core/FieldDropdown.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default class FieldDropdown extends PureComponent {
renderMenuItems(fields) {
return keys(fields).map(fieldKey => {
const field = fields[fieldKey];
const {items, key, path, label, fullLabel, altLabel, tooltip} = field;
const {items, key, path, label, fullLabel, altLabel, tooltip, disabled} = field;
const pathKey = path || key;
const option = tooltip ? <Tooltip title={tooltip}>{label}</Tooltip> : label;

Expand All @@ -46,6 +46,7 @@ export default class FieldDropdown extends PureComponent {
} else {
return <MenuItem
key={pathKey}
disabled={disabled}
>
{option}
</MenuItem>;
Expand Down
3 changes: 2 additions & 1 deletion modules/components/widgets/antd/core/FieldSelect.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export default class FieldSelect extends PureComponent {
renderSelectItems(fields) {
return keys(fields).map(fieldKey => {
const field = fields[fieldKey];
const {items, key, path, label, fullLabel, altLabel, tooltip, grouplabel} = field;
const {items, key, path, label, fullLabel, altLabel, tooltip, grouplabel, disabled} = field;
const pathKey = path || key;
if (items) {
return <OptGroup
Expand All @@ -98,6 +98,7 @@ export default class FieldSelect extends PureComponent {
title={altLabel}
grouplabel={grouplabel}
label={label}
disabled={disabled}
>
{option}
</Option>;
Expand Down
4 changes: 3 additions & 1 deletion modules/components/widgets/antd/core/FieldTreeSelect.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default class FieldTreeSelect extends PureComponent {
getTreeData(fields, fn = null) {
return keys(fields).map(fieldKey => {
const field = fields[fieldKey];
const {items, key, path, label, fullLabel, altLabel, tooltip} = field;
const {items, key, path, label, fullLabel, altLabel, tooltip, disabled} = field;
if (fn)
fn(field);
const pathKey = path || key;
Expand All @@ -63,6 +63,7 @@ export default class FieldTreeSelect extends PureComponent {
altLabel: altLabel,
fullLabel: fullLabel,
label: label,
disabled: disabled,
};
} else {
return {
Expand All @@ -71,6 +72,7 @@ export default class FieldTreeSelect extends PureComponent {
altLabel: altLabel,
fullLabel: fullLabel,
label: label,
disabled: disabled,
};
}
});
Expand Down
2 changes: 2 additions & 0 deletions modules/components/widgets/antd/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import DateTimeWidget from "./value/DateTime";
import TimeWidget from "./value/Time";
import SelectWidget from "./value/Select";
import TextWidget from "./value/Text";
import TextAreaWidget from "./value/TextArea";
import NumberWidget from "./value/Number";
import SliderWidget from "./value/Slider";
import RangeWidget from "./value/Range";
Expand Down Expand Up @@ -35,6 +36,7 @@ export default {
TimeWidget,
SelectWidget,
TextWidget,
TextAreaWidget,
NumberWidget,
SliderWidget,
RangeWidget,
Expand Down
4 changes: 2 additions & 2 deletions modules/components/widgets/antd/value/Range.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export default class RangeWidget extends PureComponent {

render() {
const {config, placeholders, customProps, value, min, max, step, marks, textSeparators, readonly} = this.props;
const {renderSize} = config.settings;
const {renderSize, defaultSliderWidth} = config.settings;
const {width, ...rest} = customProps || {};
const customInputProps = rest.input || {};
const customSliderProps = rest.slider || rest;
Expand Down Expand Up @@ -117,7 +117,7 @@ export default class RangeWidget extends PureComponent {
{...customInputProps}
/>
</Col>
<Col style={{float: "left", width: width || "300px"}}>
<Col style={{float: "left", width: width || defaultSliderWidth}}>
<Slider
disabled={readonly}
value={aValue}
Expand Down
4 changes: 2 additions & 2 deletions modules/components/widgets/antd/value/Slider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export default class SliderWidget extends PureComponent {

render() {
const {config, placeholder, customProps, value, min, max, step, marks, readonly, valueError} = this.props;
const {renderSize, showErrorMessage} = config.settings;
const {renderSize, showErrorMessage, defaultSliderWidth} = config.settings;
const {width, ...rest} = customProps || {};
const customInputProps = rest.input || {};
const customSliderProps = rest.slider || rest;
Expand All @@ -87,7 +87,7 @@ export default class SliderWidget extends PureComponent {
{...customInputProps}
/>
</Col>
<Col style={{float: "left", width: width || "300px"}}>
<Col style={{float: "left", width: width || defaultSliderWidth}}>
<Slider
disabled={readonly}
value={sliderValue}
Expand Down
4 changes: 3 additions & 1 deletion modules/components/widgets/antd/value/Text.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export default class TextWidget extends PureComponent {
field: PropTypes.string.isRequired,
readonly: PropTypes.bool,
customProps: PropTypes.object,
maxLength: PropTypes.number,
};

handleChange = (ev) => {
Expand All @@ -20,7 +21,7 @@ export default class TextWidget extends PureComponent {
}

render() {
const {config, placeholder, customProps, value, readonly} = this.props;
const {config, placeholder, customProps, value, readonly, maxLength} = this.props;
const {renderSize} = config.settings;
const aValue = value != undefined ? value : null;

Expand All @@ -33,6 +34,7 @@ export default class TextWidget extends PureComponent {
type={"text"}
value={aValue}
placeholder={placeholder}
maxLength={maxLength}
onChange={this.handleChange}
{...customProps}
/>
Expand Down
47 changes: 47 additions & 0 deletions modules/components/widgets/antd/value/TextArea.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React, { PureComponent } from "react";
import PropTypes from "prop-types";
import { Input, Col } from "antd";
const { TextArea } = Input;
const defaultMaxRows = 5;

export default class TextAreaWidget extends PureComponent {
static propTypes = {
setValue: PropTypes.func.isRequired,
placeholder: PropTypes.string,
config: PropTypes.object.isRequired,
value: PropTypes.string,
field: PropTypes.string.isRequired,
readonly: PropTypes.bool,
customProps: PropTypes.object,
maxLength: PropTypes.number,
maxRows: PropTypes.number,
};

handleChange = (ev) => {
const v = ev.target.value;
const val = v === "" ? undefined : v; // don't allow empty value
this.props.setValue(val);
}

render() {
const {config, placeholder, customProps, value, readonly, maxLength, maxRows, fullWidth} = this.props;
const {renderSize} = config.settings;
const aValue = value != undefined ? value : null;

return (
<Col>
<TextArea
autoSize={{minRows: 1, maxRows: maxRows || defaultMaxRows}}
maxLength={maxLength}
disabled={readonly}
key="widget-textarea"
size={renderSize}
value={aValue}
placeholder={placeholder}
onChange={this.handleChange}
{...customProps}
/>
</Col>
);
}
}
2 changes: 2 additions & 0 deletions modules/components/widgets/material/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import MomentUtils from "@date-io/moment";

// value widgets
import MaterialTextWidget from "./value/MaterialText";
import MaterialTextAreaWidget from "./value/MaterialTextArea";
import MaterialDateWidget from "./value/MaterialDate";
import MaterialDateTimeWidget from "./value/MaterialDateTime";
import MaterialTimeWidget from "./value/MaterialTime";
Expand Down Expand Up @@ -56,6 +57,7 @@ const MaterialProvider = ({config, children}) => {

export default {
MaterialTextWidget,
MaterialTextAreaWidget,
MaterialDateWidget,
MaterialDateTimeWidget,
MaterialTimeWidget,
Expand Down
Loading

0 comments on commit b3dc1ba

Please sign in to comment.