Skip to content

Commit

Permalink
feat(feel): provide optional toggle switch and checkbox
Browse files Browse the repository at this point in the history
Closes #194
  • Loading branch information
Niklas Kiefer committed May 10, 2023
1 parent 701c504 commit 281d6c4
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 7 deletions.
134 changes: 130 additions & 4 deletions src/components/entries/FEEL/Feel.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { forwardRef } from 'preact/compat';

import classnames from 'classnames';

import { isFunction } from 'min-dash';
import { isFunction, isString } from 'min-dash';

import {
usePrevious,
Expand All @@ -26,6 +26,8 @@ import CodeEditor from './FeelEditor';
import { FeelIndicator } from './FeelIndicator';
import FeelIcon from './FeelIcon';

import { ToggleSwitch } from '../ToggleSwitch';

const noop = () => { };

function FeelTextfield(props) {
Expand All @@ -48,8 +50,8 @@ function FeelTextfield(props) {
const editorRef = useShowEntryEvent(id);
const containerRef = useRef();

const feelActive = localValue.startsWith('=') || feel === 'required';
const feelOnlyValue = localValue.startsWith('=') ? localValue.substring(1) : localValue;
const feelActive = (isString(localValue) && localValue.startsWith('=')) || feel === 'required';
const feelOnlyValue = (isString(localValue) && localValue.startsWith('=')) ? localValue.substring(1) : localValue;

const [ focus, _setFocus ] = useState(undefined);

Expand Down Expand Up @@ -102,7 +104,7 @@ function FeelTextfield(props) {

setLocalValue(newValue);

if (!feelActive && newValue.startsWith('=')) {
if (!feelActive && isString(newValue) && newValue.startsWith('=')) {

// focus is behind `=` sign that will be removed
setFocus(-1);
Expand Down Expand Up @@ -311,6 +313,84 @@ const OptionalFeelTextArea = forwardRef((props, ref) => {
/>;
});

const OptionalFeelToggleSwitch = forwardRef((props, ref) => {
const {
id,
onInput,
value,
onFocus,
onBlur,
switcherLabel
} = props;

const inputRef = useRef();

// To be consistent with the FEEL editor, set focus at start of input
// this ensures clean editing experience when switching with the keyboard
ref.current = {
focus: () => {
const input = inputRef.current;
if (!input) {
return;
}

input.focus();
}
};

return <ToggleSwitch
id={ id }
value={ value }
inputRef={ inputRef }
onInput={ onInput }
onFocus={ onFocus }
onBlur={ onBlur }
switcherLabel={ switcherLabel } />;
});


const OptionalFeelCheckbox = forwardRef((props, ref) => {
const {
id,
disabled,
onInput,
value,
onFocus,
onBlur
} = props;

const inputRef = useRef();

const handleChange = ({ target }) => {
onInput(target.checked);
};

// To be consistent with the FEEL editor, set focus at start of input
// this ensures clean editing experience when switching with the keyboard
ref.current = {
focus: () => {
const input = inputRef.current;
if (!input) {
return;
}

input.focus();
}
};

return <input
ref={ inputRef }
id={ prefixId(id) }
name={ id }
onFocus={ onFocus }
onBlur={ onBlur }
type="checkbox"
class="bio-properties-panel-input"
onChange={ handleChange }
checked={ value }
disabled={ disabled } />;
});

/**
* @param {Object} props
* @param {Object} props.element
Expand Down Expand Up @@ -456,6 +536,52 @@ export function FeelTextAreaEntry(props) {
return <FeelEntry class="bio-properties-panel-feel-textarea" OptionalComponent={ OptionalFeelTextArea } { ...props } />;
}

/**
* @param {Object} props
* @param {Object} props.element
* @param {String} props.id
* @param {String} props.description
* @param {Boolean} props.debounce
* @param {Boolean} props.disabled
* @param {Boolean} props.feel
* @param {String} props.label
* @param {Function} props.getValue
* @param {Function} props.setValue
* @param {Function} props.tooltipContainer
* @param {Function} props.validate
* @param {Function} props.show
* @param {Function} props.example
* @param {Function} props.variables
* @param {Function} props.onFocus
* @param {Function} props.onBlur
*/
export function FeelToggleSwitchEntry(props) {
return <FeelEntry class="bio-properties-panel-feel-toggle-switch" OptionalComponent={ OptionalFeelToggleSwitch } { ...props } />;
}

/**
* @param {Object} props
* @param {Object} props.element
* @param {String} props.id
* @param {String} props.description
* @param {Boolean} props.debounce
* @param {Boolean} props.disabled
* @param {Boolean} props.feel
* @param {String} props.label
* @param {Function} props.getValue
* @param {Function} props.setValue
* @param {Function} props.tooltipContainer
* @param {Function} props.validate
* @param {Function} props.show
* @param {Function} props.example
* @param {Function} props.variables
* @param {Function} props.onFocus
* @param {Function} props.onBlur
*/
export function FeelCheckboxEntry(props) {
return <FeelEntry class="bio-properties-panel-feel-checkbox" OptionalComponent={ OptionalFeelCheckbox } { ...props } />;
}

/**
* @param {Object} props
* @param {Object} props.element
Expand Down
6 changes: 4 additions & 2 deletions src/components/entries/ToggleSwitch.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ import {
useState
} from 'preact/hooks';

function ToggleSwitch(props) {
export function ToggleSwitch(props) {
const {
id,
label,
onInput,
value,
switcherLabel,
onFocus,
onBlur
onBlur,
inputRef
} = props;

const [ localValue, setLocalValue ] = useState(value);
Expand Down Expand Up @@ -44,6 +45,7 @@ function ToggleSwitch(props) {
<div class="bio-properties-panel-field-wrapper">
<label class="bio-properties-panel-toggle-switch__switcher">
<input
ref={ inputRef }
id={ prefixId(id) }
class="bio-properties-panel-input"
type="checkbox"
Expand Down
9 changes: 8 additions & 1 deletion src/components/entries/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
export { default as CheckboxEntry, isEdited as isCheckboxEntryEdited } from './Checkbox';
export { default as CollapsibleEntry } from './Collapsible';
export { default as DescriptionEntry } from './Description';
export { default as FeelEntry, FeelTextAreaEntry, FeelTemplatingEntry, isEdited as isFeelEntryEdited } from './FEEL';
export {
default as FeelEntry,
FeelCheckboxEntry,
FeelTextAreaEntry,
FeelTemplatingEntry,
FeelToggleSwitchEntry,
isEdited as isFeelEntryEdited
} from './FEEL';
export { default as TemplatingEntry, isEdited as isTemplatingEntryEdited } from './templating';
export { default as ListEntry } from './List';
export { default as NumberFieldEntry, isEdited as isNumberFieldEntryEdited } from './NumberField';
Expand Down

0 comments on commit 281d6c4

Please sign in to comment.