Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forms typed validate #12

Merged
merged 7 commits into from
Jul 18, 2024
Merged

Forms typed validate #12

merged 7 commits into from
Jul 18, 2024

Conversation

seanhess
Copy link
Owner

The Forms in 0.3 didn't support a "Known to be Valid" state, which is required for my app. This design is common in signup forms, when you confirm that a username is available, and the field turns green.

This branch expands the Validated options into the following. It also supports type-based indexing on the Validation type, using type-level lists. So forms now know which fields they contain, based on that type-level list, and the Validation must match. See Example.Forms

data Validated fs a = Invalid Text | NotInvalid | Valid
  deriving (Show)

newtype Validation (fs :: [Type]) = Validation [(Text, Validated fs ())]
  deriving newtype (Semigroup, Monoid, Show)

I also changed the Mod for field to (Validated fs a -> Mod), which makes it easy to customize the style for the entire field at once based on the state. It makes it slightly less easy to set default styles on the field, but those can also be set on a nested container or the input itself. Accessing the Validated fs a for the field otherwise requires calling fieldValid.

@kfigiela Have you played with forms yet? I'd love some feedback: I'm unsure about the design. It supports many use-cases, but I wish that the validation states were customizable / composable (not easy to do without complicating the types significantly).

@seanhess
Copy link
Owner Author

Pushed an example that makes Validated generic, theoretically allowing the user to specify their own validated type

@seanhess
Copy link
Owner Author

There's an alternative approach, where instead of each field indexing off a different type, we use a record:

data UserForm f = UserForm
  { user :: Field f User
  , age :: Field f Int
  }
  
type family Field (f :: Type -> Type)
type instance Field Identity a = a
type instance Field Labels a = Text


Then you can customize the type the form is dealing with using that Field type family. So UserForm Identity would have values, and UserForm Labels would have text labels.

It's cool, but it's not obvious how to make it easy to carry the field names around (ideally based on selector fields), and also give the user the custom data/validation/whatever they want

@seanhess seanhess force-pushed the forms-typed-validate branch 2 times, most recently from d35a4c5 to e04ad8f Compare June 27, 2024 16:09
@seanhess seanhess merged commit 559dfcb into main Jul 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant