Skip to content

Commit

Permalink
ready for release candidate
Browse files Browse the repository at this point in the history
  • Loading branch information
Zwiterrion committed Apr 11, 2022
1 parent 0c34f77 commit 5d98b13
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 37 deletions.
8 changes: 4 additions & 4 deletions examples/src/Playground.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export const Playground = () => {
setSchema(e)
}}
/>
{/* <CodeInput
<CodeInput
mode="javascript"
onChange={e => {
try {
Expand All @@ -87,17 +87,17 @@ export const Playground = () => {
}
}}
value={typeof schema === 'object' ? JSON.stringify(schema, null, 2) : schema}
/> */}
/>
<label>Default value</label>
{/* <CodeInput
<CodeInput
mode="json"
onChange={e => {
try {
setValue(JSON.parse(e))
} catch (_) { }
}}
value={typeof value === 'object' ? JSON.stringify(value, null, 2) : value}
/> */}
/>
</div>
<div className='col-4 px-2'>
<label>Generated form</label>
Expand Down
7 changes: 6 additions & 1 deletion src/constraints.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const maxSize = (ref, message = `size is excedeed ${ref}`) => (r) => {
//mixed
export const nullable = () => (r) => r.nullable().optional().transform(v => {
const { type } = r.describe()
switch (type) {
switch (type) {
case 'string':
case 'number':
return (v || '').toString().length <= 0 ? null : v
Expand All @@ -86,6 +86,10 @@ export const when = (ref, test, then = [], otherwise = []) => (r, key, dependenc
}
export const oneOf = (arrayOfValues, message = `This value must be one of ${arrayOfValues.join(', ')}`) => (r) => r.oneOf(arrayOfValues.map(maybeRef), message)

export const blacklist = (arrayOfValues, message = `This value can't include the following values ${arrayOfValues.join(', ')}`) => (r) => r.test('blacklist' + Date.now(), message, value => {
return !arrayOfValues.some(f => value.includes(f))
})

export const ref = (ref) => yup.ref(ref)
const maybeRef = (x) => x?.ref ? ref(x.ref) : x

Expand All @@ -112,6 +116,7 @@ export const jsonConstraints = {
test: (c) => test(c.name, c.message, c.test),
when: ({ ref, test, then = [], otherwise = [] }) => when(ref, test, then, otherwise),
oneOf: ({ arrayOfValues, message = `This value must be one of ${arrayOfValues.join(', ')}` }) => oneOf(arrayOfValues, message),
blacklist: ({ arrayOfValues, message = `This value can't include the following values ${arrayOfValues.join(', ')}` }) => blacklist(arrayOfValues, message),
ref: (val) => ref(val.ref),
nullable: () => nullable()
}
2 changes: 2 additions & 0 deletions src/controlledInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ export const ControlledInput = ({ defaultValue, step, entry, children, component
}

const error = entry.split('.').reduce((acc, curr) => acc && acc[curr], errors)

console.log("render controlled input " + entry)

return (
<CustomizableInput
Expand Down
82 changes: 50 additions & 32 deletions src/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,22 @@ export const validate = (flow, schema, value) => {
})
}

const Watcher = ({ options, control, schema }) => {
const data = useWatch({ control });

if (options.watch) {
if (typeof options.watch === 'function') {
options.watch(cleanOutputArray(data, schema))
} else {
console.group('react-form watch')
console.log(cleanOutputArray(data, schema))
console.groupEnd()
}
}

return null
}

export const Form = React.forwardRef(({ schema, flow, value, inputWrapper, onSubmit, onError = () => { }, footer, style = {}, className, options = {} }, ref) => {
const classes = useCustomStyle(style)
const formFlow = flow || Object.keys(schema)
Expand Down Expand Up @@ -186,44 +202,30 @@ export const Form = React.forwardRef(({ schema, flow, value, inputWrapper, onSub
resolver: (data, context, options) => yupResolver(resolver(data))(data, context, options),
defaultValues: cleanInputArray(value, defaultValues, flow, schema),
shouldFocusError: false,
mode: 'onChange'
mode: 'onSubmit' // onChange triggers re-rendering
});

const { handleSubmit, formState: { errors, dirtyFields }, reset, watch, trigger, getValues } = methods
const { handleSubmit, formState: { errors, dirtyFields }, reset, trigger, getValues } = methods

useEffect(() => {
console.log('re-render cauz trigger')
trigger()
}, [trigger])

useEffect(() => {
if (value) {
console.log('reset from value/reset effect')
reset(cleanInputArray(value, defaultValues, flow, schema))
}
console.log('re-render cauz value/reset changed')
reset(cleanInputArray(value, defaultValues, flow, schema))
}, [value, reset])

useEffect(() => {
console.log('reset from schema effect')
console.log('re-render cauz schema changed')
reset(cleanInputArray(value, defaultValues, flow, schema))
}, [schema])

const data = watch();

if (!!options.autosubmit) {
handleSubmit(data => onSubmit(cleanOutputArray(data, schema)), onError)()
}

if (options.watch) {
if (typeof options.watch === 'function') {
console.log('call watch')
options.watch(cleanOutputArray(data, schema))
} else {
console.group('react-form watch')
console.log(cleanOutputArray(data, schema))
console.groupEnd()
}
}

const functionalProperty = (entry, prop) => {
if (typeof prop === 'function') {
return prop({ rawValues: getValues(), value: getValues(entry) });
Expand All @@ -243,7 +245,8 @@ export const Form = React.forwardRef(({ schema, flow, value, inputWrapper, onSub
}));

return (
<FormProvider {...methods} >
<FormProvider {...methods}>
<Watcher options={options} control={methods.control} schema={schema} />
<form className={className || `${classes.pr_15} ${classes.w_100}`} onSubmit={handleSubmit(data => {
const clean = cleanOutputArray(data, schema)
onSubmit(clean)
Expand All @@ -264,6 +267,7 @@ export const Form = React.forwardRef(({ schema, flow, value, inputWrapper, onSub
.map(visible => {
switch (typeof visible) {
case 'object':
console.log('watch from visibleStep')
const value = watch(step.visible.ref);
return option(step.visible.test).map(test => test(value, idx)).getOrElse(value)
case 'boolean':
Expand Down Expand Up @@ -314,6 +318,8 @@ const Step = ({ entry, realEntry, step, schema, inputWrapper, httpClient, defaul
const classes = useCustomStyle();
const { formState: { errors, dirtyFields, touchedFields, isSubmitted }, control, trigger, getValues, setValue, watch, register } = useFormContext();

console.log("re-render : " + entry)

if (entry && typeof entry === 'object') {
const errored = entry.flow.some(step => !!errors[step] && (dirtyFields[step] || touchedFields[step]))
return (
Expand All @@ -334,6 +340,7 @@ const Step = ({ entry, realEntry, step, schema, inputWrapper, httpClient, defaul
.map(visible => {
switch (typeof visible) {
case 'object':
console.log("watch of collapse")
const value = watch(visible.ref);
return option(visible.test).map(test => test(value, index)).getOrElse(value)
case 'boolean':
Expand Down Expand Up @@ -365,19 +372,30 @@ const Step = ({ entry, realEntry, step, schema, inputWrapper, httpClient, defaul
const isTouched = entry.split('.').reduce((acc, curr) => acc && acc[curr], touchedFields)
const errorDisplayed = !!error && (isSubmitted || isDirty || isTouched)

const data = watch()
const newData = cleanOutputArray(data, schema)
const onAfterChangeFunc = onAfterChange || step.onAfterChange || step.on_after_change

if (onAfterChangeFunc) {
onAfterChangeFunc({
entry,
value: getValues(entry),
getValue: e => getValues(e),
rawValues: newData,
setValue,
onChange: v => setValue(entry, v)
})
const data = watch()

const d = entry
.replace('[', '.').replace(']', '')
.split('.')
.reduce((acc, curr) => acc && acc[curr], data) || {}

const currentData = usePrevious(cleanOutputArray(d, schema))

const newData = cleanOutputArray(d, schema)

if (!deepEqual(newData, currentData))
onAfterChangeFunc({
entry,
previousValue: currentData,
value: getValues(entry),
getValue: e => getValues(e),
rawValues: newData,
setValue,
onChange: v => setValue(entry, v)
})
}

if (step.array) {
Expand Down Expand Up @@ -539,7 +557,7 @@ const Step = ({ entry, realEntry, step, schema, inputWrapper, httpClient, defaul
try {
v = JSON.parse(e)
} catch (err) {
v = {}
v = e
}
field.onChange(v)
option(step.onChange)
Expand Down

0 comments on commit 5d98b13

Please sign in to comment.