diff options
Diffstat (limited to 'web/source/settings/lib/form/index.js')
-rw-r--r-- | web/source/settings/lib/form/index.js | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/web/source/settings/lib/form/index.js b/web/source/settings/lib/form/index.js index aef3bf0d2..38e426baa 100644 --- a/web/source/settings/lib/form/index.js +++ b/web/source/settings/lib/form/index.js @@ -18,15 +18,52 @@ "use strict"; +const React = require("react"); +const getByDot = require("get-by-dot").default; + function capitalizeFirst(str) { - return str.slice(0, 1).toUpperCase() + str.slice(1); + return str.slice(0, 1).toUpperCase + str.slice(1); +} + +function selectorByKey(key) { + if (key.includes("[")) { + // get-by-dot does not support 'nested[deeper][key]' notation, convert to 'nested.deeper.key' + key = key + .replace(/\[/g, ".") // nested.deeper].key] + .replace(/\]/g, ""); // nested.deeper.key + } + + return function selector(obj) { + if (obj == undefined) { + return undefined; + } else { + return getByDot(obj, key); + } + }; } -function makeHook(func) { - return (name, ...args) => func({ - name, - Name: capitalizeFirst(name) - }, ...args); +function makeHook(hookFunction) { + return function (name, opts = {}) { + // for dynamically generating attributes like 'setName' + const Name = React.useMemo(() => capitalizeFirst(name), [name]); + + const selector = React.useMemo(() => selectorByKey(name), [name]); + const valueSelector = opts.valueSelector ?? selector; + + opts.initialValue = React.useMemo(() => { + if (opts.source == undefined) { + return opts.defaultValue; + } else { + return valueSelector(opts.source) ?? opts.defaultValue; + } + }, [opts.source, opts.defaultValue, valueSelector]); + + const hook = hookFunction({ name, Name }, opts); + + return Object.assign(hook, { + name, Name, + }); + }; } module.exports = { |