@bpmn-io/form-js-viewer 1.0.0-alpha.0 → 1.0.0-alpha.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/assets/form-js-base.css +3 -4
- package/dist/assets/form-js.css +3 -4
- package/dist/index.cjs +154 -131
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +155 -132
- package/dist/index.es.js.map +1 -1
- package/dist/types/render/hooks/index.d.ts +1 -0
- package/dist/types/render/hooks/useSingleLineTemplateEvaluation.d.ts +17 -0
- package/package.json +2 -2
|
@@ -250,6 +250,9 @@
|
|
|
250
250
|
.fjs-container .fjs-form-field-label {
|
|
251
251
|
display: flex;
|
|
252
252
|
align-items: center;
|
|
253
|
+
white-space: nowrap;
|
|
254
|
+
overflow: hidden;
|
|
255
|
+
color: var(--color-text-light);
|
|
253
256
|
}
|
|
254
257
|
|
|
255
258
|
.fjs-container .fjs-incollapsible-label {
|
|
@@ -264,10 +267,6 @@
|
|
|
264
267
|
letter-spacing: var(--letter-spacing-label);
|
|
265
268
|
}
|
|
266
269
|
|
|
267
|
-
.fjs-container .fjs-form-field-label {
|
|
268
|
-
color: var(--color-text-light);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
270
|
.fjs-container .fjs-form-field-description {
|
|
272
271
|
color: var(--color-text-lighter);
|
|
273
272
|
}
|
package/dist/assets/form-js.css
CHANGED
|
@@ -234,6 +234,9 @@
|
|
|
234
234
|
.fjs-container .fjs-form-field-label {
|
|
235
235
|
display: flex;
|
|
236
236
|
align-items: center;
|
|
237
|
+
white-space: nowrap;
|
|
238
|
+
overflow: hidden;
|
|
239
|
+
color: var(--color-text-light);
|
|
237
240
|
}
|
|
238
241
|
|
|
239
242
|
.fjs-container .fjs-incollapsible-label {
|
|
@@ -248,10 +251,6 @@
|
|
|
248
251
|
letter-spacing: var(--letter-spacing-label);
|
|
249
252
|
}
|
|
250
253
|
|
|
251
|
-
.fjs-container .fjs-form-field-label {
|
|
252
|
-
color: var(--color-text-light);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
254
|
.fjs-container .fjs-form-field-description {
|
|
256
255
|
color: var(--color-text-lighter);
|
|
257
256
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -1342,8 +1342,8 @@ function createFormContainer(prefix = 'fjs') {
|
|
|
1342
1342
|
return container;
|
|
1343
1343
|
}
|
|
1344
1344
|
|
|
1345
|
-
const EXPRESSION_PROPERTIES = ['alt', 'source', 'readonly', 'text'];
|
|
1346
|
-
const TEMPLATE_PROPERTIES = ['text'];
|
|
1345
|
+
const EXPRESSION_PROPERTIES = ['alt', 'description', 'label', 'source', 'readonly', 'text'];
|
|
1346
|
+
const TEMPLATE_PROPERTIES = ['description', 'label', 'text'];
|
|
1347
1347
|
function findErrors(errors, path) {
|
|
1348
1348
|
return errors[pathStringify(path)];
|
|
1349
1349
|
}
|
|
@@ -1697,16 +1697,162 @@ const FormContext = preact.createContext({
|
|
|
1697
1697
|
});
|
|
1698
1698
|
var FormContext$1 = FormContext;
|
|
1699
1699
|
|
|
1700
|
+
function useService(type, strict) {
|
|
1701
|
+
const {
|
|
1702
|
+
getService
|
|
1703
|
+
} = hooks.useContext(FormContext$1);
|
|
1704
|
+
return getService(type, strict);
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
/**
|
|
1708
|
+
* Returns the conditionally filtered data of a form reactively.
|
|
1709
|
+
* Memoised to minimize re-renders
|
|
1710
|
+
*
|
|
1711
|
+
*/
|
|
1712
|
+
function useFilteredFormData() {
|
|
1713
|
+
const {
|
|
1714
|
+
initialData,
|
|
1715
|
+
data
|
|
1716
|
+
} = useService('form')._getState();
|
|
1717
|
+
const conditionChecker = useService('conditionChecker', false);
|
|
1718
|
+
return hooks.useMemo(() => {
|
|
1719
|
+
const newData = conditionChecker ? conditionChecker.applyConditions(data, data) : data;
|
|
1720
|
+
return {
|
|
1721
|
+
...initialData,
|
|
1722
|
+
...newData
|
|
1723
|
+
};
|
|
1724
|
+
}, [conditionChecker, data, initialData]);
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
/**
|
|
1728
|
+
* Evaluate if condition is met reactively based on the conditionChecker and form data.
|
|
1729
|
+
*
|
|
1730
|
+
* @param {string | undefined} condition
|
|
1731
|
+
*
|
|
1732
|
+
* @returns {boolean} true if condition is met or no condition or condition checker exists
|
|
1733
|
+
*/
|
|
1734
|
+
function useCondition(condition) {
|
|
1735
|
+
const conditionChecker = useService('conditionChecker', false);
|
|
1736
|
+
const filteredData = useFilteredFormData();
|
|
1737
|
+
return hooks.useMemo(() => {
|
|
1738
|
+
return conditionChecker ? conditionChecker.check(condition, filteredData) : null;
|
|
1739
|
+
}, [conditionChecker, condition, filteredData]);
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
/**
|
|
1743
|
+
* Evaluate a string reactively based on the expressionLanguage and form data.
|
|
1744
|
+
* If the string is not an expression, it is returned as is.
|
|
1745
|
+
* Memoised to minimize re-renders.
|
|
1746
|
+
*
|
|
1747
|
+
* @param {string} value
|
|
1748
|
+
*
|
|
1749
|
+
*/
|
|
1750
|
+
function useExpressionEvaluation(value) {
|
|
1751
|
+
const formData = useFilteredFormData();
|
|
1752
|
+
const expressionLanguage = useService('expressionLanguage');
|
|
1753
|
+
return hooks.useMemo(() => {
|
|
1754
|
+
if (expressionLanguage && expressionLanguage.isExpression(value)) {
|
|
1755
|
+
return expressionLanguage.evaluate(value, formData);
|
|
1756
|
+
}
|
|
1757
|
+
return value;
|
|
1758
|
+
}, [expressionLanguage, formData, value]);
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
function useKeyDownAction(targetKey, action, listenerElement = window) {
|
|
1762
|
+
function downHandler({
|
|
1763
|
+
key
|
|
1764
|
+
}) {
|
|
1765
|
+
if (key === targetKey) {
|
|
1766
|
+
action();
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
hooks.useEffect(() => {
|
|
1770
|
+
listenerElement.addEventListener('keydown', downHandler);
|
|
1771
|
+
return () => {
|
|
1772
|
+
listenerElement.removeEventListener('keydown', downHandler);
|
|
1773
|
+
};
|
|
1774
|
+
});
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
/**
|
|
1778
|
+
* Retrieve readonly value of a form field, given it can be an
|
|
1779
|
+
* expression optionally or configured globally.
|
|
1780
|
+
*
|
|
1781
|
+
* @typedef { import('../../types').FormProperties } FormProperties
|
|
1782
|
+
*
|
|
1783
|
+
* @param {any} formField
|
|
1784
|
+
* @param {FormProperties} properties
|
|
1785
|
+
*
|
|
1786
|
+
* @returns {boolean}
|
|
1787
|
+
*/
|
|
1788
|
+
function useReadonly(formField, properties = {}) {
|
|
1789
|
+
const expressionLanguage = useService('expressionLanguage');
|
|
1790
|
+
const conditionChecker = useService('conditionChecker', false);
|
|
1791
|
+
const filteredData = useFilteredFormData();
|
|
1792
|
+
const {
|
|
1793
|
+
readonly
|
|
1794
|
+
} = formField;
|
|
1795
|
+
if (properties.readOnly) {
|
|
1796
|
+
return true;
|
|
1797
|
+
}
|
|
1798
|
+
if (expressionLanguage && expressionLanguage.isExpression(readonly)) {
|
|
1799
|
+
return conditionChecker ? conditionChecker.check(readonly, filteredData) : false;
|
|
1800
|
+
}
|
|
1801
|
+
return readonly || false;
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
/**
|
|
1805
|
+
* Template a string reactively based on form data. If the string is not a template, it is returned as is.
|
|
1806
|
+
* Memoised to minimize re-renders
|
|
1807
|
+
*
|
|
1808
|
+
* @param {string} value
|
|
1809
|
+
* @param {Object} options
|
|
1810
|
+
* @param {boolean} [options.debug = false]
|
|
1811
|
+
* @param {boolean} [options.strict = false]
|
|
1812
|
+
* @param {Function} [options.buildDebugString]
|
|
1813
|
+
*
|
|
1814
|
+
*/
|
|
1815
|
+
function useTemplateEvaluation(value, options) {
|
|
1816
|
+
const filteredData = useFilteredFormData();
|
|
1817
|
+
const templating = useService('templating');
|
|
1818
|
+
return hooks.useMemo(() => {
|
|
1819
|
+
if (templating && templating.isTemplate(value)) {
|
|
1820
|
+
return templating.evaluate(value, filteredData, options);
|
|
1821
|
+
}
|
|
1822
|
+
return value;
|
|
1823
|
+
}, [filteredData, templating, value, options]);
|
|
1824
|
+
}
|
|
1825
|
+
|
|
1826
|
+
/**
|
|
1827
|
+
* Template a string reactively based on form data. If the string is not a template, it is returned as is.
|
|
1828
|
+
* If the string contains multiple lines, only the first line is returned.
|
|
1829
|
+
* Memoised to minimize re-renders
|
|
1830
|
+
*
|
|
1831
|
+
* @param {string} value
|
|
1832
|
+
* @param {Object} [options]
|
|
1833
|
+
* @param {boolean} [options.debug = false]
|
|
1834
|
+
* @param {boolean} [options.strict = false]
|
|
1835
|
+
* @param {Function} [options.buildDebugString]
|
|
1836
|
+
*
|
|
1837
|
+
*/
|
|
1838
|
+
function useSingleLineTemplateEvaluation(value, options = {}) {
|
|
1839
|
+
const evaluatedTemplate = useTemplateEvaluation(value, options);
|
|
1840
|
+
return hooks.useMemo(() => evaluatedTemplate && evaluatedTemplate.split('\n')[0], [evaluatedTemplate]);
|
|
1841
|
+
}
|
|
1842
|
+
|
|
1700
1843
|
function Description(props) {
|
|
1701
1844
|
const {
|
|
1702
1845
|
description
|
|
1703
1846
|
} = props;
|
|
1704
|
-
|
|
1847
|
+
const evaluatedDescription = useSingleLineTemplateEvaluation(description || '', {
|
|
1848
|
+
debug: true
|
|
1849
|
+
});
|
|
1850
|
+
if (!evaluatedDescription) {
|
|
1705
1851
|
return null;
|
|
1706
1852
|
}
|
|
1707
1853
|
return jsxRuntime.jsx("div", {
|
|
1708
1854
|
class: "fjs-form-field-description",
|
|
1709
|
-
children:
|
|
1855
|
+
children: evaluatedDescription
|
|
1710
1856
|
});
|
|
1711
1857
|
}
|
|
1712
1858
|
|
|
@@ -1739,12 +1885,15 @@ function Label(props) {
|
|
|
1739
1885
|
collapseOnEmpty = true,
|
|
1740
1886
|
required = false
|
|
1741
1887
|
} = props;
|
|
1888
|
+
const evaluatedLabel = useSingleLineTemplateEvaluation(label || '', {
|
|
1889
|
+
debug: true
|
|
1890
|
+
});
|
|
1742
1891
|
return jsxRuntime.jsxs("label", {
|
|
1743
1892
|
for: id,
|
|
1744
1893
|
class: classNames('fjs-form-field-label', {
|
|
1745
1894
|
'fjs-incollapsible-label': !collapseOnEmpty
|
|
1746
1895
|
}, props['class']),
|
|
1747
|
-
children: [props.children,
|
|
1896
|
+
children: [props.children, evaluatedLabel, required && jsxRuntime.jsx("span", {
|
|
1748
1897
|
class: "fjs-asterix",
|
|
1749
1898
|
children: "*"
|
|
1750
1899
|
})]
|
|
@@ -1871,13 +2020,6 @@ function _isValueSomething(value) {
|
|
|
1871
2020
|
return value || value === 0 || value === false;
|
|
1872
2021
|
}
|
|
1873
2022
|
|
|
1874
|
-
function useService(type, strict) {
|
|
1875
|
-
const {
|
|
1876
|
-
getService
|
|
1877
|
-
} = hooks.useContext(FormContext$1);
|
|
1878
|
-
return getService(type, strict);
|
|
1879
|
-
}
|
|
1880
|
-
|
|
1881
2023
|
/**
|
|
1882
2024
|
* @enum { String }
|
|
1883
2025
|
*/
|
|
@@ -2251,125 +2393,6 @@ Checklist.config = {
|
|
|
2251
2393
|
}
|
|
2252
2394
|
};
|
|
2253
2395
|
|
|
2254
|
-
/**
|
|
2255
|
-
* Returns the conditionally filtered data of a form reactively.
|
|
2256
|
-
* Memoised to minimize re-renders
|
|
2257
|
-
*
|
|
2258
|
-
*/
|
|
2259
|
-
function useFilteredFormData() {
|
|
2260
|
-
const {
|
|
2261
|
-
initialData,
|
|
2262
|
-
data
|
|
2263
|
-
} = useService('form')._getState();
|
|
2264
|
-
const conditionChecker = useService('conditionChecker', false);
|
|
2265
|
-
return hooks.useMemo(() => {
|
|
2266
|
-
const newData = conditionChecker ? conditionChecker.applyConditions(data, data) : data;
|
|
2267
|
-
return {
|
|
2268
|
-
...initialData,
|
|
2269
|
-
...newData
|
|
2270
|
-
};
|
|
2271
|
-
}, [conditionChecker, data, initialData]);
|
|
2272
|
-
}
|
|
2273
|
-
|
|
2274
|
-
/**
|
|
2275
|
-
* Evaluate if condition is met reactively based on the conditionChecker and form data.
|
|
2276
|
-
*
|
|
2277
|
-
* @param {string | undefined} condition
|
|
2278
|
-
*
|
|
2279
|
-
* @returns {boolean} true if condition is met or no condition or condition checker exists
|
|
2280
|
-
*/
|
|
2281
|
-
function useCondition(condition) {
|
|
2282
|
-
const conditionChecker = useService('conditionChecker', false);
|
|
2283
|
-
const filteredData = useFilteredFormData();
|
|
2284
|
-
return hooks.useMemo(() => {
|
|
2285
|
-
return conditionChecker ? conditionChecker.check(condition, filteredData) : null;
|
|
2286
|
-
}, [conditionChecker, condition, filteredData]);
|
|
2287
|
-
}
|
|
2288
|
-
|
|
2289
|
-
/**
|
|
2290
|
-
* Evaluate a string reactively based on the expressionLanguage and form data.
|
|
2291
|
-
* If the string is not an expression, it is returned as is.
|
|
2292
|
-
* Memoised to minimize re-renders.
|
|
2293
|
-
*
|
|
2294
|
-
* @param {string} value
|
|
2295
|
-
*
|
|
2296
|
-
*/
|
|
2297
|
-
function useExpressionEvaluation(value) {
|
|
2298
|
-
const formData = useFilteredFormData();
|
|
2299
|
-
const expressionLanguage = useService('expressionLanguage');
|
|
2300
|
-
return hooks.useMemo(() => {
|
|
2301
|
-
if (expressionLanguage && expressionLanguage.isExpression(value)) {
|
|
2302
|
-
return expressionLanguage.evaluate(value, formData);
|
|
2303
|
-
}
|
|
2304
|
-
return value;
|
|
2305
|
-
}, [expressionLanguage, formData, value]);
|
|
2306
|
-
}
|
|
2307
|
-
|
|
2308
|
-
function useKeyDownAction(targetKey, action, listenerElement = window) {
|
|
2309
|
-
function downHandler({
|
|
2310
|
-
key
|
|
2311
|
-
}) {
|
|
2312
|
-
if (key === targetKey) {
|
|
2313
|
-
action();
|
|
2314
|
-
}
|
|
2315
|
-
}
|
|
2316
|
-
hooks.useEffect(() => {
|
|
2317
|
-
listenerElement.addEventListener('keydown', downHandler);
|
|
2318
|
-
return () => {
|
|
2319
|
-
listenerElement.removeEventListener('keydown', downHandler);
|
|
2320
|
-
};
|
|
2321
|
-
});
|
|
2322
|
-
}
|
|
2323
|
-
|
|
2324
|
-
/**
|
|
2325
|
-
* Retrieve readonly value of a form field, given it can be an
|
|
2326
|
-
* expression optionally or configured globally.
|
|
2327
|
-
*
|
|
2328
|
-
* @typedef { import('../../types').FormProperties } FormProperties
|
|
2329
|
-
*
|
|
2330
|
-
* @param {any} formField
|
|
2331
|
-
* @param {FormProperties} properties
|
|
2332
|
-
*
|
|
2333
|
-
* @returns {boolean}
|
|
2334
|
-
*/
|
|
2335
|
-
function useReadonly(formField, properties = {}) {
|
|
2336
|
-
const expressionLanguage = useService('expressionLanguage');
|
|
2337
|
-
const conditionChecker = useService('conditionChecker', false);
|
|
2338
|
-
const filteredData = useFilteredFormData();
|
|
2339
|
-
const {
|
|
2340
|
-
readonly
|
|
2341
|
-
} = formField;
|
|
2342
|
-
if (properties.readOnly) {
|
|
2343
|
-
return true;
|
|
2344
|
-
}
|
|
2345
|
-
if (expressionLanguage && expressionLanguage.isExpression(readonly)) {
|
|
2346
|
-
return conditionChecker ? conditionChecker.check(readonly, filteredData) : false;
|
|
2347
|
-
}
|
|
2348
|
-
return readonly || false;
|
|
2349
|
-
}
|
|
2350
|
-
|
|
2351
|
-
/**
|
|
2352
|
-
* Template a string reactively based on form data. If the string is not a template, it is returned as is.
|
|
2353
|
-
* Memoised to minimize re-renders
|
|
2354
|
-
*
|
|
2355
|
-
* @param {string} value
|
|
2356
|
-
* @param {Object} options
|
|
2357
|
-
* @param {boolean} [options.debug = false]
|
|
2358
|
-
* @param {boolean} [options.strict = false]
|
|
2359
|
-
* @param {Function} [options.buildDebugString]
|
|
2360
|
-
*
|
|
2361
|
-
*/
|
|
2362
|
-
function useTemplateEvaluation(value, options) {
|
|
2363
|
-
const filteredData = useFilteredFormData();
|
|
2364
|
-
const templating = useService('templating');
|
|
2365
|
-
return hooks.useMemo(() => {
|
|
2366
|
-
if (templating.isTemplate(value)) {
|
|
2367
|
-
return templating.evaluate(value, filteredData, options);
|
|
2368
|
-
}
|
|
2369
|
-
return value;
|
|
2370
|
-
}, [filteredData, templating, value, options]);
|
|
2371
|
-
}
|
|
2372
|
-
|
|
2373
2396
|
const noop$1 = () => false;
|
|
2374
2397
|
function FormField(props) {
|
|
2375
2398
|
const {
|