@bpmn-io/properties-panel 1.4.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -10,6 +10,7 @@ var jsxRuntime = require('../preact/jsx-runtime');
10
10
  var minDom = require('min-dom');
11
11
  var preact = require('../preact');
12
12
  var FeelEditor = require('@bpmn-io/feel-editor');
13
+ var feelers = require('feelers');
13
14
 
14
15
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
15
16
 
@@ -961,7 +962,7 @@ function ListItem(props) {
961
962
  });
962
963
  }
963
964
 
964
- const noop$2 = () => {};
965
+ const noop$3 = () => {};
965
966
 
966
967
  /**
967
968
  * @param {import('../PropertiesPanel').ListGroupDefinition} props
@@ -1070,7 +1071,7 @@ function ListGroup(props) {
1070
1071
  ref: groupRef,
1071
1072
  children: [jsxRuntime.jsxs("div", {
1072
1073
  class: classnames__default["default"]('bio-properties-panel-group-header', hasItems ? '' : 'empty', hasItems && open ? 'open' : '', sticky && open ? 'sticky' : ''),
1073
- onClick: hasItems ? toggleOpen : noop$2,
1074
+ onClick: hasItems ? toggleOpen : noop$3,
1074
1075
  children: [jsxRuntime.jsx("div", {
1075
1076
  title: label,
1076
1077
  class: "bio-properties-panel-group-header-title",
@@ -1251,7 +1252,7 @@ function CheckboxEntry(props) {
1251
1252
  })]
1252
1253
  });
1253
1254
  }
1254
- function isEdited$7(node) {
1255
+ function isEdited$8(node) {
1255
1256
  return node && !!node.checked;
1256
1257
  }
1257
1258
 
@@ -1261,7 +1262,7 @@ function prefixId$7(id) {
1261
1262
  return `bio-properties-panel-${id}`;
1262
1263
  }
1263
1264
 
1264
- const useBufferedFocus = function (editor, ref) {
1265
+ const useBufferedFocus$1 = function (editor, ref) {
1265
1266
  const [buffer, setBuffer] = hooks.useState(undefined);
1266
1267
  ref.current = hooks.useMemo(() => ({
1267
1268
  focus: offset => {
@@ -1282,7 +1283,7 @@ const useBufferedFocus = function (editor, ref) {
1282
1283
  }
1283
1284
  }, [editor, buffer]);
1284
1285
  };
1285
- const CodeEditor = compat.forwardRef((props, ref) => {
1286
+ const CodeEditor$1 = compat.forwardRef((props, ref) => {
1286
1287
  const {
1287
1288
  value,
1288
1289
  onInput,
@@ -1295,7 +1296,7 @@ const CodeEditor = compat.forwardRef((props, ref) => {
1295
1296
  const inputRef = hooks.useRef();
1296
1297
  const [editor, setEditor] = hooks.useState();
1297
1298
  const [localValue, setLocalValue] = hooks.useState(value || '');
1298
- useBufferedFocus(editor, ref);
1299
+ useBufferedFocus$1(editor, ref);
1299
1300
  const handleInput = useStaticCallback(newValue => {
1300
1301
  onInput(newValue);
1301
1302
  setLocalValue(newValue);
@@ -1377,7 +1378,7 @@ function FeelIndicator(props) {
1377
1378
  });
1378
1379
  }
1379
1380
 
1380
- const noop$1 = () => {};
1381
+ const noop$2 = () => {};
1381
1382
 
1382
1383
  /**
1383
1384
  * @param {Object} props
@@ -1390,7 +1391,7 @@ function FeelIcon(props) {
1390
1391
  feel = false,
1391
1392
  active,
1392
1393
  disabled = false,
1393
- onClick = noop$1
1394
+ onClick = noop$2
1394
1395
  } = props;
1395
1396
  const feelRequiredLabel = ' must be a FEEL expression';
1396
1397
  const feelOptionalLabel = ' can optionally be a FEEL expression';
@@ -1411,7 +1412,7 @@ function FeelIcon(props) {
1411
1412
  });
1412
1413
  }
1413
1414
 
1414
- const noop = () => {};
1415
+ const noop$1 = () => {};
1415
1416
  function FeelTextfield(props) {
1416
1417
  const {
1417
1418
  debounce,
@@ -1551,7 +1552,7 @@ function FeelTextfield(props) {
1551
1552
  active: feelActive,
1552
1553
  disabled: feel !== 'optional' || disabled,
1553
1554
  onClick: handleFeelToggle
1554
- }), feelActive ? jsxRuntime.jsx(CodeEditor, {
1555
+ }), feelActive ? jsxRuntime.jsx(CodeEditor$1, {
1555
1556
  id: prefixId$6(id),
1556
1557
  name: id,
1557
1558
  onInput: handleLocalInput,
@@ -1664,10 +1665,17 @@ const OptionalFeelTextArea = compat.forwardRef((props, ref) => {
1664
1665
  * @param {String} props.description
1665
1666
  * @param {Boolean} props.debounce
1666
1667
  * @param {Boolean} props.disabled
1668
+ * @param {Boolean} props.feel
1667
1669
  * @param {String} props.label
1668
1670
  * @param {Function} props.getValue
1669
1671
  * @param {Function} props.setValue
1672
+ * @param {Function} props.tooltipContainer
1670
1673
  * @param {Function} props.validate
1674
+ * @param {Function} props.show
1675
+ * @param {Function} props.example
1676
+ * @param {Function} props.variables
1677
+ * @param {Function} props.onFocus
1678
+ * @param {Function} props.onBlur
1671
1679
  */
1672
1680
  function FeelEntry(props) {
1673
1681
  const {
@@ -1682,7 +1690,7 @@ function FeelEntry(props) {
1682
1690
  setValue,
1683
1691
  tooltipContainer,
1684
1692
  validate,
1685
- show = noop,
1693
+ show = noop$1,
1686
1694
  example,
1687
1695
  variables,
1688
1696
  onFocus,
@@ -1759,12 +1767,17 @@ function FeelEntry(props) {
1759
1767
  * @param {String} props.description
1760
1768
  * @param {Boolean} props.debounce
1761
1769
  * @param {Boolean} props.disabled
1770
+ * @param {Boolean} props.feel
1762
1771
  * @param {String} props.label
1763
1772
  * @param {Function} props.getValue
1764
1773
  * @param {Function} props.setValue
1774
+ * @param {Function} props.tooltipContainer
1775
+ * @param {Function} props.validate
1776
+ * @param {Function} props.show
1777
+ * @param {Function} props.example
1778
+ * @param {Function} props.variables
1765
1779
  * @param {Function} props.onFocus
1766
1780
  * @param {Function} props.onBlur
1767
- * @param {Function} props.validate
1768
1781
  */
1769
1782
  function FeelTextArea(props) {
1770
1783
  return jsxRuntime.jsx(FeelEntry, {
@@ -1773,7 +1786,7 @@ function FeelTextArea(props) {
1773
1786
  ...props
1774
1787
  });
1775
1788
  }
1776
- function isEdited$6(node) {
1789
+ function isEdited$7(node) {
1777
1790
  return node && (!!node.value || node.classList.contains('edited'));
1778
1791
  }
1779
1792
 
@@ -1783,6 +1796,260 @@ function prefixId$6(id) {
1783
1796
  return `bio-properties-panel-${id}`;
1784
1797
  }
1785
1798
 
1799
+ const useBufferedFocus = function (editor, ref) {
1800
+ const [buffer, setBuffer] = hooks.useState(undefined);
1801
+ ref.current = hooks.useMemo(() => ({
1802
+ focus: offset => {
1803
+ if (editor) {
1804
+ editor.focus(offset);
1805
+ } else {
1806
+ if (typeof offset === 'undefined') {
1807
+ offset = Infinity;
1808
+ }
1809
+ setBuffer(offset);
1810
+ }
1811
+ }
1812
+ }), [editor]);
1813
+ hooks.useEffect(() => {
1814
+ if (typeof buffer !== 'undefined' && editor) {
1815
+ editor.focus(buffer);
1816
+ setBuffer(false);
1817
+ }
1818
+ }, [editor, buffer]);
1819
+ };
1820
+ const CodeEditor = compat.forwardRef((props, ref) => {
1821
+ const {
1822
+ value,
1823
+ onInput,
1824
+ onLint = () => {},
1825
+ contentAttributes = {},
1826
+ disabled,
1827
+ tooltipContainer,
1828
+ useGutters = false,
1829
+ darkMode = false
1830
+ } = props;
1831
+ const inputRef = hooks.useRef();
1832
+ const [editor, setEditor] = hooks.useState();
1833
+ const [localValue, setLocalValue] = hooks.useState(value || '');
1834
+ useBufferedFocus(editor, ref);
1835
+ const handleInput = useStaticCallback(newValue => {
1836
+ onInput(newValue);
1837
+ setLocalValue(newValue);
1838
+ });
1839
+ hooks.useEffect(() => {
1840
+ let editor;
1841
+ editor = new feelers.FeelersEditor({
1842
+ container: inputRef.current,
1843
+ onChange: handleInput,
1844
+ onLint: onLint,
1845
+ contentAttributes: contentAttributes,
1846
+ tooltipContainer: tooltipContainer,
1847
+ value: localValue,
1848
+ darkMode: darkMode,
1849
+ enableGutters: useGutters
1850
+ });
1851
+ setEditor(editor);
1852
+ return () => {
1853
+ onLint([]);
1854
+ inputRef.current.innerHTML = '';
1855
+ setEditor(null);
1856
+ };
1857
+ }, []);
1858
+ hooks.useEffect(() => {
1859
+ if (!editor) {
1860
+ return;
1861
+ }
1862
+ if (value === localValue) {
1863
+ return;
1864
+ }
1865
+ editor.setValue(value);
1866
+ setLocalValue(value);
1867
+ }, [value]);
1868
+ const handleClick = () => {
1869
+ ref.current.focus();
1870
+ };
1871
+ return jsxRuntime.jsx("div", {
1872
+ name: props.name,
1873
+ class: classnames__default["default"]('bio-properties-panel-feelers-editor bio-properties-panel-input', localValue ? 'edited' : null, disabled ? 'disabled' : null),
1874
+ ref: inputRef,
1875
+ onClick: handleClick
1876
+ });
1877
+ });
1878
+
1879
+ const noop = () => {};
1880
+
1881
+ /**
1882
+ * @param {Object} props
1883
+ * @param {Object} props.element
1884
+ * @param {String} props.id
1885
+ * @param {String} props.description
1886
+ * @param {Boolean} props.debounce
1887
+ * @param {Boolean} props.disabled
1888
+ * @param {String} props.label
1889
+ * @param {Function} props.getValue
1890
+ * @param {Function} props.setValue
1891
+ * @param {Function} props.tooltipContainer
1892
+ * @param {Function} props.validate
1893
+ * @param {Function} props.show
1894
+ */
1895
+ function FeelTemplatingEntry(props) {
1896
+ const {
1897
+ element,
1898
+ id,
1899
+ description,
1900
+ debounce,
1901
+ disabled,
1902
+ label,
1903
+ getValue,
1904
+ setValue,
1905
+ tooltipContainer,
1906
+ validate,
1907
+ show = noop
1908
+ } = props;
1909
+ const [cachedInvalidValue, setCachedInvalidValue] = hooks.useState(null);
1910
+ const [validationError, setValidationError] = hooks.useState(null);
1911
+ const [localError, setLocalError] = hooks.useState(null);
1912
+ let value = getValue(element);
1913
+ const previousValue = usePrevious(value);
1914
+ hooks.useEffect(() => {
1915
+ if (minDash.isFunction(validate)) {
1916
+ const newValidationError = validate(value) || null;
1917
+ setValidationError(newValidationError);
1918
+ }
1919
+ }, [value]);
1920
+ const onInput = useStaticCallback(newValue => {
1921
+ let newValidationError = null;
1922
+ if (minDash.isFunction(validate)) {
1923
+ newValidationError = validate(newValue) || null;
1924
+ }
1925
+ if (newValidationError) {
1926
+ setCachedInvalidValue(newValue);
1927
+ } else {
1928
+ // don't create multiple commandStack entries for the same value
1929
+ if (newValue !== value) {
1930
+ setValue(newValue);
1931
+ }
1932
+ }
1933
+ setValidationError(newValidationError);
1934
+ });
1935
+ const onError = hooks.useCallback(err => {
1936
+ setLocalError(err);
1937
+ }, []);
1938
+ if (previousValue === value && validationError) {
1939
+ value = cachedInvalidValue;
1940
+ }
1941
+ const temporaryError = useError(id);
1942
+ const error = localError || temporaryError || validationError;
1943
+ return jsxRuntime.jsxs("div", {
1944
+ class: classnames__default["default"]('bio-properties-panel-entry', error ? 'has-error' : ''),
1945
+ "data-entry-id": id,
1946
+ children: [jsxRuntime.jsx(FeelTemplating, {
1947
+ debounce: debounce,
1948
+ disabled: disabled,
1949
+ id: id,
1950
+ label: label,
1951
+ onInput: onInput,
1952
+ onError: onError,
1953
+ show: show,
1954
+ value: value,
1955
+ tooltipContainer: tooltipContainer
1956
+ }, element), error && jsxRuntime.jsx("div", {
1957
+ class: "bio-properties-panel-error",
1958
+ children: error
1959
+ }), jsxRuntime.jsx(Description, {
1960
+ forId: id,
1961
+ element: element,
1962
+ value: description
1963
+ })]
1964
+ });
1965
+ }
1966
+ function FeelTemplating(props) {
1967
+ const {
1968
+ debounce,
1969
+ id,
1970
+ label,
1971
+ onInput,
1972
+ onError,
1973
+ value = '',
1974
+ disabled = false,
1975
+ tooltipContainer
1976
+ } = props;
1977
+ const [localValue, setLocalValue] = hooks.useState(value);
1978
+ const editorRef = useShowEntryEvent(id);
1979
+ const containerRef = hooks.useRef();
1980
+ const [focus, _setFocus] = hooks.useState(undefined);
1981
+ const setFocus = (offset = 0) => {
1982
+ const hasFocus = containerRef.current.contains(document.activeElement);
1983
+
1984
+ // Keep caret position if it is already focused, otherwise focus at the end
1985
+ const position = hasFocus ? document.activeElement.selectionStart : Infinity;
1986
+ _setFocus(position + offset);
1987
+ };
1988
+ const handleInputCallback = hooks.useMemo(() => {
1989
+ return debounce(newValue => onInput(newValue.length ? newValue : undefined));
1990
+ }, [onInput, debounce]);
1991
+ const handleInput = newValue => {
1992
+ handleInputCallback(newValue);
1993
+ setLocalValue(newValue);
1994
+ };
1995
+ const handleLint = useStaticCallback(lint => {
1996
+ const errors = lint && lint.length && lint.filter(e => e.severity === 'error') || [];
1997
+ if (!errors.length) {
1998
+ onError(undefined);
1999
+ return;
2000
+ }
2001
+ const error = lint[0];
2002
+ const message = `${error.source}: ${error.message}`;
2003
+ onError(message);
2004
+ });
2005
+ hooks.useEffect(() => {
2006
+ if (typeof focus !== 'undefined') {
2007
+ editorRef.current.focus(focus);
2008
+ _setFocus(undefined);
2009
+ }
2010
+ }, [focus]);
2011
+ hooks.useEffect(() => {
2012
+ if (value === localValue) {
2013
+ return;
2014
+ }
2015
+ setLocalValue(value ? value : '');
2016
+ }, [value]);
2017
+ return jsxRuntime.jsxs("div", {
2018
+ class: "bio-properties-panel-feelers",
2019
+ children: [jsxRuntime.jsx("label", {
2020
+ id: prefixIdLabel(id),
2021
+ class: "bio-properties-panel-label",
2022
+ onClick: () => setFocus(),
2023
+ children: label
2024
+ }), jsxRuntime.jsx("div", {
2025
+ class: "bio-properties-panel-feelers-input",
2026
+ ref: containerRef,
2027
+ children: jsxRuntime.jsx(CodeEditor, {
2028
+ name: id,
2029
+ onInput: handleInput,
2030
+ contentAttributes: {
2031
+ 'aria-labelledby': prefixIdLabel(id)
2032
+ },
2033
+ disabled: disabled,
2034
+ onLint: handleLint,
2035
+ value: localValue,
2036
+ useGutters: false,
2037
+ ref: editorRef,
2038
+ tooltipContainer: tooltipContainer
2039
+ })
2040
+ })]
2041
+ });
2042
+ }
2043
+ function isEdited$6(node) {
2044
+ return node && (!!node.value || node.classList.contains('edited'));
2045
+ }
2046
+
2047
+ // helpers /////////////////
2048
+
2049
+ function prefixIdLabel(id) {
2050
+ return `bio-properties-panel-feelers-${id}-label`;
2051
+ }
2052
+
1786
2053
  function List(props) {
1787
2054
  const {
1788
2055
  id,
@@ -2715,6 +2982,7 @@ exports.ExternalLinkIcon = ExternalLinkIcon;
2715
2982
  exports.FeelEntry = FeelEntry;
2716
2983
  exports.FeelOptionalIcon = FeelOptionalIcon;
2717
2984
  exports.FeelRequiredIcon = FeelRequiredIcon;
2985
+ exports.FeelTemplatingEntry = FeelTemplatingEntry;
2718
2986
  exports.FeelTextAreaEntry = FeelTextArea;
2719
2987
  exports.Group = Group;
2720
2988
  exports.Header = Header;
@@ -2732,8 +3000,9 @@ exports.SimpleEntry = Simple;
2732
3000
  exports.TextAreaEntry = TextAreaEntry;
2733
3001
  exports.TextFieldEntry = TextfieldEntry;
2734
3002
  exports.ToggleSwitchEntry = ToggleSwitchEntry;
2735
- exports.isCheckboxEntryEdited = isEdited$7;
2736
- exports.isFeelEntryEdited = isEdited$6;
3003
+ exports.isCheckboxEntryEdited = isEdited$8;
3004
+ exports.isFeelEntryEdited = isEdited$7;
3005
+ exports.isFeelTemplatingEntryEdited = isEdited$6;
2737
3006
  exports.isNumberFieldEntryEdited = isEdited$5;
2738
3007
  exports.isSelectEntryEdited = isEdited$4;
2739
3008
  exports.isSimpleEntryEdited = isEdited$3;