summaryrefslogtreecommitdiff
path: root/web/source/settings/lib/form/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'web/source/settings/lib/form/index.js')
-rw-r--r--web/source/settings/lib/form/index.js49
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 = {