Custom state validation

Right now, `FreeText` offers `opts.error`, but it is impossible to dynamically set this based on what happens in `opts.check`. The plan is to change this so that `opts.check` can return an error string or object to use as the error message.