@danderson00/react-forms 0.0.25 → 0.0.28

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/Form.js CHANGED
@@ -41,7 +41,7 @@ function _objectWithoutProperties(source, excluded) { if (source == null) return
41
41
 
42
42
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
43
43
 
44
- var _default = function _default(ContextProvider) {
44
+ var Form = function Form(ContextProvider) {
45
45
  var additionalContext = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
46
46
  var ErrorMessage = arguments.length > 2 ? arguments[2] : undefined;
47
47
  return function (_ref) {
@@ -73,6 +73,11 @@ var _default = function _default(ContextProvider) {
73
73
  setValid = _useState6[1];
74
74
 
75
75
  var form = /*#__PURE__*/(0, _react.createRef)();
76
+ (0, _react.useEffect)(function () {
77
+ if (form.current) {
78
+ setValid(form.current.checkValidity());
79
+ }
80
+ }, [form.current]);
76
81
 
77
82
  var getFieldValue = function getFieldValue(path) {
78
83
  return (0, _objectPathImmutable.get)(fieldValues, path);
@@ -189,4 +194,5 @@ var _default = function _default(ContextProvider) {
189
194
  };
190
195
  };
191
196
 
197
+ var _default = Form;
192
198
  exports["default"] = _default;
package/dist/Group.js ADDED
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = void 0;
7
+
8
+ var _react = require("react");
9
+
10
+ var _excluded = ["name"],
11
+ _excluded2 = ["groups"];
12
+
13
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
14
+
15
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
16
+
17
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
18
+
19
+ function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
20
+
21
+ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
22
+
23
+ var Group = function Group(formContext) {
24
+ return function (_ref) {
25
+ var name = _ref.name,
26
+ props = _objectWithoutProperties(_ref, _excluded);
27
+
28
+ if (!name) throw new Error("You must provide a name prop to form components");
29
+
30
+ var _useContext = (0, _react.useContext)(formContext),
31
+ _useContext$groups = _useContext.groups,
32
+ groups = _useContext$groups === void 0 ? [] : _useContext$groups,
33
+ context = _objectWithoutProperties(_useContext, _excluded2);
34
+
35
+ return /*#__PURE__*/(0, _react.createElement)(formContext.Provider, _objectSpread(_objectSpread({}, props), {}, {
36
+ value: _objectSpread(_objectSpread({}, context), {}, {
37
+ groups: groups.concat(name)
38
+ })
39
+ }));
40
+ };
41
+ };
42
+
43
+ var _default = Group;
44
+ exports["default"] = _default;
package/dist/fields.js CHANGED
@@ -14,7 +14,7 @@ var _excluded = ["label", "className"],
14
14
 
15
15
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
16
16
 
17
- function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
17
+ function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
18
18
 
19
19
  function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
20
20
 
package/dist/index.js CHANGED
@@ -10,12 +10,14 @@ Object.defineProperty(exports, "FormProvider", {
10
10
  return _Form["default"];
11
11
  }
12
12
  });
13
- exports.wrapSubmit = exports.wrapInput = exports.useFormValues = exports.createRawConsumer = exports.context = exports.Textarea = exports.Submit = exports.Select = exports.Input = void 0;
13
+ exports.wrapSubmit = exports.wrapInput = exports.useFormValues = exports.createRawConsumer = exports.context = exports.Textarea = exports.Submit = exports.Select = exports.Input = exports.Group = void 0;
14
14
 
15
15
  var _react = require("react");
16
16
 
17
17
  var _Form = _interopRequireDefault(require("./Form"));
18
18
 
19
+ var _Group = _interopRequireDefault(require("./Group"));
20
+
19
21
  var _ErrorMessage = _interopRequireDefault(require("./ErrorMessage"));
20
22
 
21
23
  var _submit = _interopRequireDefault(require("./submit"));
@@ -71,6 +73,8 @@ var createRawConsumer = function createRawConsumer(ConsumerComponent) {
71
73
  exports.createRawConsumer = createRawConsumer;
72
74
  var Form = (0, _Form["default"])(context.Provider, {}, _ErrorMessage["default"]);
73
75
  exports.Form = Form;
76
+ var Group = (0, _Group["default"])(context);
77
+ exports.Group = Group;
74
78
  var Submit = createConsumer((0, _submit["default"])(function (props) {
75
79
  return /*#__PURE__*/(0, _react.createElement)('button', props);
76
80
  }));
package/dist/input.js CHANGED
@@ -15,7 +15,7 @@ var _inputTypes = _interopRequireDefault(require("./inputTypes"));
15
15
 
16
16
  var _throttle2 = _interopRequireDefault(require("./throttle"));
17
17
 
18
- var _excluded = ["type", "name", "value", "checked", "defaultValue", "numeric", "onSubmit", "registerFieldValidator", "setFieldValue", "getFieldValue", "getFieldValues", "submitOnChange", "submitOnBlur", "selectOnFocus", "throttle", "valid"];
18
+ var _excluded = ["type", "value", "checked", "defaultValue", "numeric", "onSubmit", "registerFieldValidator", "setFieldValue", "getFieldValue", "getFieldValues", "submitOnChange", "submitOnBlur", "selectOnFocus", "throttle", "valid"];
19
19
 
20
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
21
21
 
@@ -69,12 +69,16 @@ var _default = function _default(render) {
69
69
 
70
70
  var previousValueProp = (0, _usePrevious["default"])(props.value); // this is currently broken :-\
71
71
 
72
- var throttle = props.throttle,
72
+ var _props$groups = props.groups,
73
+ groups = _props$groups === void 0 ? [] : _props$groups,
74
+ throttle = props.throttle,
73
75
  onSubmit = props.onSubmit;
76
+ var name = groups.map(function (group) {
77
+ return group + '.';
78
+ }) + props.name;
74
79
  var submitHandler = throttle && onSubmit ? (0, _throttle2["default"])(onSubmit, isNaN(throttle) ? 200 : throttle) : onSubmit;
75
80
  (0, _react.useEffect)(function () {
76
- var name = props.name,
77
- getFieldValue = props.getFieldValue,
81
+ var getFieldValue = props.getFieldValue,
78
82
  setFieldValue = props.setFieldValue,
79
83
  registerFieldValidator = props.registerFieldValidator;
80
84
 
@@ -101,8 +105,7 @@ var _default = function _default(render) {
101
105
  // this probably introduces some redundancy with the onChange handler below
102
106
 
103
107
  (0, _useUpdate["default"])(function () {
104
- var name = props.name,
105
- value = props.value,
108
+ var value = props.value,
106
109
  setFieldValue = props.setFieldValue;
107
110
 
108
111
  var _types2 = (0, _inputTypes["default"])(props, options),
@@ -111,7 +114,7 @@ var _default = function _default(render) {
111
114
  if (value !== previousValueProp) {
112
115
  setFieldValue(name, applyValueTransforms(value));
113
116
  }
114
- }, [props]);
117
+ }, [props]); // TODO: refactor bubbling to prop pattern
115
118
 
116
119
  var onChange = function onChange() {
117
120
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
@@ -119,8 +122,7 @@ var _default = function _default(render) {
119
122
  }
120
123
 
121
124
  var event = args[0];
122
- var name = props.name,
123
- setFieldValue = props.setFieldValue,
125
+ var setFieldValue = props.setFieldValue,
124
126
  onChange = props.onChange,
125
127
  submitOnChange = props.submitOnChange;
126
128
  var valueFromEvent = options.valueFromEvent;
@@ -196,6 +198,25 @@ var _default = function _default(render) {
196
198
  }
197
199
  };
198
200
 
201
+ var onKeyDown = function onKeyDown() {
202
+ var onKeyDown = props.onKeyDown;
203
+
204
+ for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
205
+ args[_key4] = arguments[_key4];
206
+ }
207
+
208
+ var event = args[0];
209
+ var element = event.target;
210
+
211
+ if (props.numeric && !/[0-9-]/.exec(event.key) && ![null, 0, 8, 9, 13, 27, 35, 36, 37, 39, 46].includes(event.keyCode)) {
212
+ event.preventDefault();
213
+ }
214
+
215
+ if (onKeyDown) {
216
+ onKeyDown.apply(element, args);
217
+ }
218
+ };
219
+
199
220
  var updateValidationState = function updateValidationState() {
200
221
  setFieldValidated(true); // this is a little hacky, but the simplest way I could think of to determine the
201
222
  // validity of the actual input element. :invalid is also not supported by enzyme
@@ -212,7 +233,6 @@ var _default = function _default(render) {
212
233
  getValueProps = _types4.getValueProps;
213
234
 
214
235
  var type = props.type,
215
- name = props.name,
216
236
  value = props.value,
217
237
  checked = props.checked,
218
238
  defaultValue = props.defaultValue,
@@ -250,7 +270,8 @@ var _default = function _default(render) {
250
270
  }, passThroughProps), valueProps), numericProps), typeProps), errorProps), {}, {
251
271
  onChange: onChange,
252
272
  onFocus: onFocus,
253
- onBlur: onBlur
273
+ onBlur: onBlur,
274
+ onKeyDown: onKeyDown
254
275
  });
255
276
 
256
277
  return render(finalProps);
@@ -22,7 +22,7 @@ var _default = function _default(props, options) {
22
22
  defaultValue = props.defaultValue;
23
23
 
24
24
  var applyValueTransforms = function applyValueTransforms(value) {
25
- return (props.type === 'number' || props.numeric) && !isNaN(+value) ? +value : value;
25
+ return (props.type === 'number' || props.numeric) && !isNaN(+value) && value !== '' ? +value : value;
26
26
  };
27
27
 
28
28
  var defaultType = {
@@ -100,7 +100,7 @@ var _default = function _default(props, options) {
100
100
  var set = _ref9.set,
101
101
  element = _ref9.element;
102
102
  set(value || defaultValue || props.options && props.options.length > 0 && props.options[0] || // this probably should come out - is it the right behavior for all browsers? it's here to keep 1 unit test happy?
103
- element && element.value // this *should* work in all browsers (except jsdom)...
103
+ element && element.value || '' // this *should* work in all browsers (except jsdom)...
104
104
  );
105
105
  }
106
106
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danderson00/react-forms",
3
- "version": "0.0.25",
3
+ "version": "0.0.28",
4
4
  "description": "Ultra simple, stateless, validated forms for use in React function components",
5
5
  "main": "dist/index.js",
6
6
  "module": "src/index.js",
@@ -13,7 +13,7 @@
13
13
  "object-path-immutable": "^4.1.1"
14
14
  },
15
15
  "peerDependencies": {
16
- "react": "^17.0.1"
16
+ "react": "*"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@babel/cli": "^7.4.4",
@@ -24,8 +24,8 @@
24
24
  "babel-jest": "26.6.0",
25
25
  "enzyme": "^3.9.0",
26
26
  "jest": "26.6.0",
27
- "react": "^17.0.1",
28
- "react-dom": "^17.0.1"
27
+ "react": "^17.0.2",
28
+ "react-dom": "^17.0.2"
29
29
  },
30
30
  "jest": {
31
31
  "moduleNameMapper": {
package/src/Form.js CHANGED
@@ -1,7 +1,7 @@
1
- import { createElement, createRef, useReducer, useState } from 'react'
1
+ import { createElement, createRef, useEffect, useReducer, useState } from 'react'
2
2
  import { get, set } from 'object-path-immutable'
3
3
 
4
- export default (ContextProvider, additionalContext = {}, ErrorMessage) => (
4
+ const Form = (ContextProvider, additionalContext = {}, ErrorMessage) => (
5
5
  ({ resetOnSubmit, row, gap, ...props }) => {
6
6
  const [fieldValues, setFieldValues] = useState(props.values || {})
7
7
  const [fieldValidators, registerFieldValidator] = useReducer((validators, validator) => [...validators, validator], [])
@@ -9,6 +9,12 @@ export default (ContextProvider, additionalContext = {}, ErrorMessage) => (
9
9
  const [valid, setValid] = useState()
10
10
  const form = createRef()
11
11
 
12
+ useEffect(() => {
13
+ if(form.current) {
14
+ setValid(form.current.checkValidity())
15
+ }
16
+ }, [form.current])
17
+
12
18
  const getFieldValue = path => get(fieldValues, path)
13
19
  const getFieldValues = () => fieldValues
14
20
  const mapFieldValues = target => Object.keys(target).reduce(
@@ -109,4 +115,5 @@ export default (ContextProvider, additionalContext = {}, ErrorMessage) => (
109
115
  })
110
116
  )
111
117
  }
112
- )
118
+ )
119
+ export default Form
package/src/Group.js ADDED
@@ -0,0 +1,15 @@
1
+ import { createElement, useContext } from 'react'
2
+
3
+ const Group = formContext => ({ name, ...props }) => {
4
+ if (!name) throw new Error("You must provide a name prop to form components")
5
+ const { groups = [], ...context } = useContext(formContext)
6
+
7
+ return createElement(formContext.Provider, {
8
+ ...props,
9
+ value: {
10
+ ...context,
11
+ groups: groups.concat(name)
12
+ }
13
+ })
14
+ }
15
+ export default Group
package/src/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { createContext, createElement } from 'react'
2
2
  import FormProvider from './Form'
3
+ import GroupProvider from './Group'
3
4
  import ErrorMessage from './ErrorMessage'
4
5
  import submit from './submit'
5
6
  import input from './input'
@@ -23,6 +24,7 @@ export const createRawConsumer = ConsumerComponent => (
23
24
  )
24
25
 
25
26
  export const Form = FormProvider(context.Provider, {}, ErrorMessage)
27
+ export const Group = GroupProvider(context)
26
28
  export const Submit = createConsumer(submit(props => createElement('button', props)))
27
29
 
28
30
  export const Input = createConsumer(input(props => createElement('input', props)))
package/src/input.js CHANGED
@@ -16,11 +16,12 @@ export default (render, options = {}) => function Input(props) {
16
16
  const previousValueProp = usePrevious(props.value)
17
17
 
18
18
  // this is currently broken :-\
19
- const { throttle, onSubmit } = props
19
+ const { groups = [], throttle, onSubmit } = props
20
+ const name = groups.map(group => group + '.') + props.name
20
21
  const submitHandler = (throttle && onSubmit) ? createThrottled(onSubmit, isNaN(throttle) ? 200 : throttle) : onSubmit
21
22
 
22
23
  useEffect(() => {
23
- const { name, getFieldValue, setFieldValue, registerFieldValidator } = props
24
+ const { getFieldValue, setFieldValue, registerFieldValidator } = props
24
25
  const { setInitialValue, applyValueTransforms } = types(props, options)
25
26
 
26
27
  // don't override values that were set from passing a values prop to the form
@@ -43,7 +44,7 @@ export default (render, options = {}) => function Input(props) {
43
44
  // ensure form values are updated to reflect passed `value` prop
44
45
  // this probably introduces some redundancy with the onChange handler below
45
46
  useUpdate(() => {
46
- const { name, value, setFieldValue } = props
47
+ const { value, setFieldValue } = props
47
48
  const { applyValueTransforms } = types(props, options)
48
49
 
49
50
  if(value !== previousValueProp) {
@@ -51,9 +52,10 @@ export default (render, options = {}) => function Input(props) {
51
52
  }
52
53
  }, [props])
53
54
 
55
+ // TODO: refactor bubbling to prop pattern
54
56
  const onChange = (...args) => {
55
57
  const [event] = args
56
- const { name, setFieldValue, onChange, submitOnChange } = props
58
+ const { setFieldValue, onChange, submitOnChange } = props
57
59
  const { valueFromEvent } = options
58
60
  const { getOutputValue, applyValueTransforms } = types(props, options)
59
61
 
@@ -110,6 +112,21 @@ export default (render, options = {}) => function Input(props) {
110
112
  }
111
113
  }
112
114
 
115
+ const onKeyDown = (...args) => {
116
+ const { onKeyDown } = props
117
+ const [event] = args
118
+ const element = event.target
119
+
120
+ if(props.numeric && !/[0-9-]/.exec(event.key) && ![null, 0, 8, 9, 13, 27, 35, 36, 37, 39, 46].includes(event.keyCode)) {
121
+ event.preventDefault()
122
+ }
123
+
124
+ if(onKeyDown) {
125
+ onKeyDown.apply(element, args)
126
+ }
127
+ }
128
+
129
+
113
130
  const updateValidationState = () => {
114
131
  setFieldValidated(true)
115
132
  // this is a little hacky, but the simplest way I could think of to determine the
@@ -122,7 +139,7 @@ export default (render, options = {}) => function Input(props) {
122
139
  const { getValueProps } = types(props, options)
123
140
 
124
141
  const {
125
- type, name, value, checked, defaultValue, numeric,
142
+ type, value, checked, defaultValue, numeric,
126
143
  onSubmit, registerFieldValidator, setFieldValue, getFieldValue, getFieldValues,
127
144
  submitOnChange, submitOnBlur, selectOnFocus, throttle, valid,
128
145
  ...passThroughProps
@@ -136,7 +153,7 @@ export default (render, options = {}) => function Input(props) {
136
153
  const finalProps = {
137
154
  id, name, className,
138
155
  ...passThroughProps, ...valueProps, ...numericProps, ...typeProps, ...errorProps,
139
- onChange, onFocus, onBlur
156
+ onChange, onFocus, onBlur, onKeyDown
140
157
  }
141
158
 
142
159
  return render(finalProps)
package/src/inputTypes.js CHANGED
@@ -3,7 +3,7 @@ const resolveValue = (value, args) => typeof value === 'function' ? value.apply(
3
3
  export default (props, options) => {
4
4
  const { type, checked, value, defaultValue } = props
5
5
 
6
- const applyValueTransforms = value => ((props.type === 'number' || props.numeric) && !isNaN(+value)) ? +value : value
6
+ const applyValueTransforms = value => ((props.type === 'number' || props.numeric) && !isNaN(+value) && value !== '') ? +value : value
7
7
 
8
8
  const defaultType = {
9
9
  setInitialValue: ({ set }) => {
@@ -53,7 +53,7 @@ export default (props, options) => {
53
53
  setInitialValue: ({ set, element }) => {
54
54
  set(value || defaultValue ||
55
55
  (props.options && props.options.length > 0 && props.options[0]) || // this probably should come out - is it the right behavior for all browsers? it's here to keep 1 unit test happy?
56
- element && element.value // this *should* work in all browsers (except jsdom)...
56
+ element && element.value || '' // this *should* work in all browsers (except jsdom)...
57
57
  )
58
58
  }
59
59
  }