Skip to content

Commit

Permalink
Release v2.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
kutyel committed May 8, 2024
1 parent f2f298c commit 0c21c19
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 92 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ Generate validating forms from JSON schemas.
- Generates all common types of input fields (`text`, `select`, etc.) with optional labels and descriptions.
- Error messages can easily be customized as needed.
- Supports custom string formats using validation functions (similar to Json decoders).
- Comes with default Bootstrap and Tailwind CSS themes in the `Theme` object, that can also be customised.

## Warnings

1. The way form fields are generated and presented is very opinionated and thus not always suitable for general case usage. This library is intended to be used for cases where you have control over how the schema is structured.
2. The HTML that the library outputs is intended to be used together with [Tailwind CSS](https://tailwindcss.com/) to style the form. It can of course be used without Tailwind but some field types might need some custom styling to look ok.
3. There is currently no support for linked schemas using `$ref`.
2. There is currently no support for linked schemas using `$ref`.

## Example usage

Expand All @@ -32,6 +32,7 @@ import Html exposing (..)
import Html.Events exposing (onSubmit)
import Json.Schema
import Json.Schema.Form exposing (Msg, State)
import Json.Schema.Form.Theme as Theme


main : Program () State Msg
Expand Down Expand Up @@ -61,6 +62,7 @@ init =
Json.Schema.Form.init
{ errors = \path error -> "Invalid field: " ++ path
, formats = Dict.empty
, theme = Theme.default
}
schema_

Expand Down
2 changes: 1 addition & 1 deletion elm.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "scrive/json-schema-form",
"summary": "Generate validating forms from JSON schemas.",
"license": "MIT",
"version": "1.0.3",
"version": "2.0.0",
"exposed-modules": [
"Json.Schema.Form",
"Json.Schema.Form.Encode",
Expand Down
88 changes: 1 addition & 87 deletions example/Main.elm
Original file line number Diff line number Diff line change
Expand Up @@ -26,100 +26,14 @@ main =
Browser.sandbox { init = init, update = update, view = view }


tailwind : Theme
tailwind =
let
theme =
Theme.default

isInvalid =
"border-2 border-red-500"
in
{ theme
| -- inputs
txt =
\{ withError, format } ->
Attrs.classList
[ ( "block w-full rounded-md py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6", True )
, ( "border-0", not withError )
, ( isInvalid, withError )
, case format of
Just str ->
( "format-" ++ str, True )

Nothing ->
( "", False )
]

-- checkbox
, checkboxWrapper = Attrs.class "flex h-6 items-center"
, checkboxInput =
\{ withError } ->
Attrs.classList
[ ( "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600", True )
, ( isInvalid, withError )
]
, checkboxTitle = Attrs.class "ml-3 text-sm leading-6"

-- select
, select =
\{ withError } ->
Attrs.classList
[ ( "block w-full mt-2 rounded-md py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:max-w-xs sm:text-sm sm:leading-6", True )
, ( "border-0", not withError )
, ( isInvalid, withError )
]

-- list group
, listGroup = Attrs.class "mb-2"
, listGroupItem = Attrs.class "border border-gray-300 rounded-md px-4 py-2 mb-2 shadow-sm"
, listGroupAddItemButton = Attrs.class "rounded-md bg-gray-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-gray-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-600"
, listGroupRemoveItemButton = Attrs.class "rounded-md bg-white px-2.5 py-1.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50"

-- tuple
, formRow = Attrs.class "flex space-x-4"
, formRowItem = Attrs.class "max-w-full flex-grow"

-- radio
, radioWrapper = Attrs.class "flex items-center gap-x-3"
, radioInput = Attrs.class "h-4 w-4 border-gray-300 text-indigo-600 focus:ring-indigo-600"
, radioInputLabel = Attrs.class "block text-sm font-medium leading-6 text-gray-900"
, field =
\{ withError, withValue } ->
Attrs.classList
[ ( "mb-6", True )
, ( "text-red-500", withError )
, ( "has-value", withValue )
]
, fieldLabel = Attrs.class "block"
, fieldInput = Attrs.class "field-input"
, fieldInputMeta = Attrs.class "field-meta"
, fieldTitle = Attrs.class "block text-sm font-medium leading-6 text-gray-900"
, fieldDescription = Attrs.class "mt-2 text-sm leading-6 text-gray-600"
, group =
\{ withError, withValue } ->
Attrs.classList
[ ( "mb-4", True )
, ( "text-red-500", withError )
, ( "has-value", withValue )
]
, liveError = Attrs.class "text-red-500 text-xs my-2"
, inputGroupPrepend = Attrs.class "inline-flex items-center rounded-l-md border border-r-0 border-gray-300 px-3 text-gray-500 sm:text-sm"
, inputGroupPrependContent = Attrs.class "text-gray-500 sm:text-sm"
, inputGroupAppend = Attrs.class "inline-flex items-center rounded-r-md border border-l-0 border-gray-300 px-3 text-gray-500 sm:text-sm"
, inputGroupAppendContent = Attrs.class "text-gray-500 sm:text-sm"
, inputGroup = Attrs.class "mt-2 flex shadow-sm"
}


init : State
init =
case schema of
Ok schema_ ->
Json.Schema.Form.init
{ errors = errorString
, formats = Dict.fromList formats
, theme = tailwind
, theme = Theme.tailwind
}
schema_

Expand Down
89 changes: 87 additions & 2 deletions src/Json/Schema/Form/Theme.elm
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module Json.Schema.Form.Theme exposing (Theme, default)
module Json.Schema.Form.Theme exposing (Theme, default, tailwind)

{-| Theme allows you to set styling of generated Form elements
@docs Theme, default
@docs Theme, default, tailwind
-}

Expand Down Expand Up @@ -123,3 +123,88 @@ default =
, inputGroupAppendContent = Attrs.class "input-group-text"
, inputGroup = Attrs.class "input-group"
}


{-| Optional tailwindcss theme
-}
tailwind : Theme
tailwind =
let
isInvalid =
"border-2 border-red-500"
in
{ default
| -- inputs
txt =
\{ withError, format } ->
Attrs.classList
[ ( "block w-full rounded-md py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6", True )
, ( "border-0", not withError )
, ( isInvalid, withError )
, case format of
Just str ->
( "format-" ++ str, True )

Nothing ->
( "", False )
]

-- checkbox
, checkboxWrapper = Attrs.class "flex h-6 items-center"
, checkboxInput =
\{ withError } ->
Attrs.classList
[ ( "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600", True )
, ( isInvalid, withError )
]
, checkboxTitle = Attrs.class "ml-3 text-sm leading-6"

-- select
, select =
\{ withError } ->
Attrs.classList
[ ( "block w-full mt-2 rounded-md py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:max-w-xs sm:text-sm sm:leading-6", True )
, ( "border-0", not withError )
, ( isInvalid, withError )
]

-- list group
, listGroup = Attrs.class "mb-2"
, listGroupItem = Attrs.class "border border-gray-300 rounded-md px-4 py-2 mb-2 shadow-sm"
, listGroupAddItemButton = Attrs.class "rounded-md bg-gray-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-gray-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-600"
, listGroupRemoveItemButton = Attrs.class "rounded-md bg-white px-2.5 py-1.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50"

-- tuple
, formRow = Attrs.class "flex space-x-4"
, formRowItem = Attrs.class "max-w-full flex-grow"

-- radio
, radioWrapper = Attrs.class "flex items-center gap-x-3"
, radioInput = Attrs.class "h-4 w-4 border-gray-300 text-indigo-600 focus:ring-indigo-600"
, radioInputLabel = Attrs.class "block text-sm font-medium leading-6 text-gray-900"
, field =
\{ withError, withValue } ->
Attrs.classList
[ ( "mb-6", True )
, ( "text-red-500", withError )
, ( "has-value", withValue )
]
, fieldLabel = Attrs.class "block"
, fieldInput = Attrs.class "field-input"
, fieldInputMeta = Attrs.class "field-meta"
, fieldTitle = Attrs.class "block text-sm font-medium leading-6 text-gray-900"
, fieldDescription = Attrs.class "mt-2 text-sm leading-6 text-gray-600"
, group =
\{ withError, withValue } ->
Attrs.classList
[ ( "mb-4", True )
, ( "text-red-500", withError )
, ( "has-value", withValue )
]
, liveError = Attrs.class "text-red-500 text-xs my-2"
, inputGroupPrepend = Attrs.class "inline-flex items-center rounded-l-md border border-r-0 border-gray-300 px-3 text-gray-500 sm:text-sm"
, inputGroupPrependContent = Attrs.class "text-gray-500 sm:text-sm"
, inputGroupAppend = Attrs.class "inline-flex items-center rounded-r-md border border-l-0 border-gray-300 px-3 text-gray-500 sm:text-sm"
, inputGroupAppendContent = Attrs.class "text-gray-500 sm:text-sm"
, inputGroup = Attrs.class "mt-2 flex shadow-sm"
}

0 comments on commit 0c21c19

Please sign in to comment.