index.js (2496B)
1 /* 2 GoToSocial 3 Copyright (C) GoToSocial Authors admin@gotosocial.org 4 SPDX-License-Identifier: AGPL-3.0-or-later 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU Affero General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU Affero General Public License for more details. 15 16 You should have received a copy of the GNU Affero General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 "use strict"; 21 22 const React = require("react"); 23 const getByDot = require("get-by-dot").default; 24 25 function capitalizeFirst(str) { 26 return str.slice(0, 1).toUpperCase + str.slice(1); 27 } 28 29 function selectorByKey(key) { 30 if (key.includes("[")) { 31 // get-by-dot does not support 'nested[deeper][key]' notation, convert to 'nested.deeper.key' 32 key = key 33 .replace(/\[/g, ".") // nested.deeper].key] 34 .replace(/\]/g, ""); // nested.deeper.key 35 } 36 37 return function selector(obj) { 38 if (obj == undefined) { 39 return undefined; 40 } else { 41 return getByDot(obj, key); 42 } 43 }; 44 } 45 46 function makeHook(hookFunction) { 47 return function (name, opts = {}) { 48 // for dynamically generating attributes like 'setName' 49 const Name = React.useMemo(() => capitalizeFirst(name), [name]); 50 51 const selector = React.useMemo(() => selectorByKey(name), [name]); 52 const valueSelector = opts.valueSelector ?? selector; 53 54 opts.initialValue = React.useMemo(() => { 55 if (opts.source == undefined) { 56 return opts.defaultValue; 57 } else { 58 return valueSelector(opts.source) ?? opts.defaultValue; 59 } 60 }, [opts.source, opts.defaultValue, valueSelector]); 61 62 const hook = hookFunction({ name, Name }, opts); 63 64 return Object.assign(hook, { 65 name, Name, 66 }); 67 }; 68 } 69 70 module.exports = { 71 useTextInput: makeHook(require("./text")), 72 useFileInput: makeHook(require("./file")), 73 useBoolInput: makeHook(require("./bool")), 74 useRadioInput: makeHook(require("./radio")), 75 useComboBoxInput: makeHook(require("./combo-box")), 76 useCheckListInput: makeHook(require("./check-list")), 77 useFieldArrayInput: makeHook(require("./field-array")), 78 useValue: function (name, value) { 79 return { 80 name, 81 value, 82 hasChanged: () => true // always included 83 }; 84 } 85 };