{-|
Module: IHP.View.CSSFramework
Description: Adds support for bootstrap, tailwind, etc. to IHP
Copyright: (c) digitally induced GmbH, 2020
-}
module IHP.View.CSSFramework where

import IHP.Prelude
import IHP.FlashMessages.Types
import qualified Text.Blaze.Html5 as Blaze
import IHP.HSX.QQ (hsx)
import IHP.HSX.ToHtml ()
import IHP.View.Types
import IHP.View.Classes

import IHP.ModelSupport
import IHP.Breadcrumb.Types
import IHP.Pagination.Helpers
import IHP.Pagination.Types
import IHP.View.Types (PaginationView(linkPrevious, pagination))


-- | Provides an unstyled CSSFramework
--
-- This way we can later add more properties to the CSSFramework without having update all the CSS Frameworks manually
instance Default CSSFramework where
    def :: CSSFramework
def = CSSFramework :: (CSSFramework -> FlashMessage -> Html)
-> (CSSFramework -> [FlashMessage] -> Html)
-> (CSSFramework -> FormField -> Html)
-> (CSSFramework -> Text -> FormField -> Html -> Html)
-> (CSSFramework -> FormField -> Html -> Html)
-> (CSSFramework -> FormField -> Html -> Html)
-> (CSSFramework -> FormField -> Html -> Html)
-> (CSSFramework -> Text -> Html -> Html)
-> (CSSFramework -> SubmitButton -> Html)
-> Text
-> (CSSFramework -> FormField -> Html)
-> (CSSFramework -> FormField -> Text)
-> (CSSFramework -> FormField -> Text)
-> Text
-> (CSSFramework -> FormField -> Html)
-> Text
-> (CSSFramework -> PaginationView -> Html)
-> (CSSFramework -> Pagination -> ByteString -> Html)
-> (CSSFramework -> Pagination -> ByteString -> Html)
-> (CSSFramework -> Pagination -> ByteString -> Int -> Html)
-> (CSSFramework -> Pagination -> Html)
-> (CSSFramework -> Pagination -> (Int -> ByteString) -> Html)
-> (CSSFramework -> [BreadcrumbItem] -> BreadcrumbsView -> Html)
-> (CSSFramework
    -> [BreadcrumbItem] -> BreadcrumbItem -> Bool -> Html)
-> CSSFramework
CSSFramework
            {
                $sel:styledFlashMessage:CSSFramework :: CSSFramework -> FlashMessage -> Html
styledFlashMessage = \CSSFramework
cssFramework -> \case
                        SuccessFlashMessage Text
message -> [hsx|<div>{message}</div>|]
                        ErrorFlashMessage Text
message -> [hsx|<div>{message}</div>|]
                , CSSFramework -> [FlashMessage] -> Html
forall mono.
(MonoFoldable mono, Element mono ~ FlashMessage) =>
CSSFramework -> mono -> Html
$sel:styledFlashMessages:CSSFramework :: CSSFramework -> [FlashMessage] -> Html
styledFlashMessages :: forall mono.
(MonoFoldable mono, Element mono ~ FlashMessage) =>
CSSFramework -> mono -> Html
styledFlashMessages
                , CSSFramework -> FormField -> Html
$sel:styledFormField:CSSFramework :: CSSFramework -> FormField -> Html
styledFormField :: CSSFramework -> FormField -> Html
styledFormField
                , CSSFramework -> Text -> FormField -> Html -> Html
$sel:styledTextFormField:CSSFramework :: CSSFramework -> Text -> FormField -> Html -> Html
styledTextFormField :: CSSFramework -> Text -> FormField -> Html -> Html
styledTextFormField
                , CSSFramework -> FormField -> Html -> Html
$sel:styledTextareaFormField:CSSFramework :: CSSFramework -> FormField -> Html -> Html
styledTextareaFormField :: CSSFramework -> FormField -> Html -> Html
styledTextareaFormField
                , CSSFramework -> FormField -> Html -> Html
$sel:styledCheckboxFormField:CSSFramework :: CSSFramework -> FormField -> Html -> Html
styledCheckboxFormField :: CSSFramework -> FormField -> Html -> Html
styledCheckboxFormField
                , CSSFramework -> FormField -> Html -> Html
$sel:styledSelectFormField:CSSFramework :: CSSFramework -> FormField -> Html -> Html
styledSelectFormField :: CSSFramework -> FormField -> Html -> Html
styledSelectFormField
                , CSSFramework -> Text -> Html -> Html
$sel:styledFormGroup:CSSFramework :: CSSFramework -> Text -> Html -> Html
styledFormGroup :: CSSFramework -> Text -> Html -> Html
styledFormGroup
                , CSSFramework -> SubmitButton -> Html
forall model.
HasField "styledSubmitButtonClass" model Text =>
model -> SubmitButton -> Html
$sel:styledSubmitButton:CSSFramework :: CSSFramework -> SubmitButton -> Html
styledSubmitButton :: forall model.
HasField "styledSubmitButtonClass" model Text =>
model -> SubmitButton -> Html
styledSubmitButton
                , Text
$sel:styledSubmitButtonClass:CSSFramework :: Text
styledSubmitButtonClass :: Text
styledSubmitButtonClass
                , CSSFramework -> FormField -> Html
forall p. p -> FormField -> Html
$sel:styledFormFieldHelp:CSSFramework :: CSSFramework -> FormField -> Html
styledFormFieldHelp :: forall p. p -> FormField -> Html
styledFormFieldHelp
                , CSSFramework -> FormField -> Text
forall p p p. IsString p => p -> p -> p
$sel:styledInputClass:CSSFramework :: CSSFramework -> FormField -> Text
styledInputClass :: forall p p p. IsString p => p -> p -> p
styledInputClass
                , CSSFramework -> FormField -> Text
forall p p p. IsString p => p -> p -> p
$sel:styledInputInvalidClass:CSSFramework :: CSSFramework -> FormField -> Text
styledInputInvalidClass :: forall p p p. IsString p => p -> p -> p
styledInputInvalidClass
                , Text
$sel:styledFormGroupClass:CSSFramework :: Text
styledFormGroupClass :: Text
styledFormGroupClass
                , CSSFramework -> FormField -> Html
$sel:styledValidationResult:CSSFramework :: CSSFramework -> FormField -> Html
styledValidationResult :: CSSFramework -> FormField -> Html
styledValidationResult
                , Text
$sel:styledValidationResultClass:CSSFramework :: Text
styledValidationResultClass :: Text
styledValidationResultClass
                , CSSFramework -> PaginationView -> Html
$sel:styledPagination:CSSFramework :: CSSFramework -> PaginationView -> Html
styledPagination :: CSSFramework -> PaginationView -> Html
styledPagination
                , CSSFramework -> Pagination -> ByteString -> Int -> Html
$sel:styledPaginationPageLink:CSSFramework :: CSSFramework -> Pagination -> ByteString -> Int -> Html
styledPaginationPageLink :: CSSFramework -> Pagination -> ByteString -> Int -> Html
styledPaginationPageLink
                , CSSFramework -> Pagination -> Html
$sel:styledPaginationDotDot:CSSFramework :: CSSFramework -> Pagination -> Html
styledPaginationDotDot :: CSSFramework -> Pagination -> Html
styledPaginationDotDot
                , CSSFramework -> Pagination -> (Int -> ByteString) -> Html
$sel:styledPaginationItemsPerPageSelector:CSSFramework :: CSSFramework -> Pagination -> (Int -> ByteString) -> Html
styledPaginationItemsPerPageSelector :: CSSFramework -> Pagination -> (Int -> ByteString) -> Html
styledPaginationItemsPerPageSelector
                , CSSFramework -> Pagination -> ByteString -> Html
$sel:styledPaginationLinkPrevious:CSSFramework :: CSSFramework -> Pagination -> ByteString -> Html
styledPaginationLinkPrevious :: CSSFramework -> Pagination -> ByteString -> Html
styledPaginationLinkPrevious
                , CSSFramework -> Pagination -> ByteString -> Html
$sel:styledPaginationLinkNext:CSSFramework :: CSSFramework -> Pagination -> ByteString -> Html
styledPaginationLinkNext :: CSSFramework -> Pagination -> ByteString -> Html
styledPaginationLinkNext
                , CSSFramework -> [BreadcrumbItem] -> BreadcrumbsView -> Html
$sel:styledBreadcrumb:CSSFramework :: CSSFramework -> [BreadcrumbItem] -> BreadcrumbsView -> Html
styledBreadcrumb :: CSSFramework -> [BreadcrumbItem] -> BreadcrumbsView -> Html
styledBreadcrumb
                , CSSFramework -> [BreadcrumbItem] -> BreadcrumbItem -> Bool -> Html
$sel:styledBreadcrumbItem:CSSFramework :: CSSFramework -> [BreadcrumbItem] -> BreadcrumbItem -> Bool -> Html
styledBreadcrumbItem :: CSSFramework -> [BreadcrumbItem] -> BreadcrumbItem -> Bool -> Html
styledBreadcrumbItem
            }
        where
            styledFlashMessages :: CSSFramework -> mono -> Html
styledFlashMessages CSSFramework
cssFramework mono
flashMessages = mono -> (Element mono -> Html) -> Html
forall mono (m :: * -> *).
(MonoFoldable mono, Applicative m) =>
mono -> (Element mono -> m ()) -> m ()
forEach mono
flashMessages (CSSFramework -> CSSFramework -> FlashMessage -> Html
styledFlashMessage CSSFramework
cssFramework CSSFramework
cssFramework)

            styledFormField :: CSSFramework -> FormField -> Blaze.Html
            styledFormField :: CSSFramework -> FormField -> Html
styledFormField cssFramework :: CSSFramework
cssFramework@CSSFramework {CSSFramework -> FormField -> Html
styledValidationResult :: CSSFramework -> FormField -> Html
$sel:styledValidationResult:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Html
styledValidationResult, CSSFramework -> Text -> FormField -> Html -> Html
styledTextFormField :: CSSFramework -> Text -> FormField -> Html -> Html
$sel:styledTextFormField:CSSFramework :: CSSFramework -> CSSFramework -> Text -> FormField -> Html -> Html
styledTextFormField, CSSFramework -> FormField -> Html -> Html
styledCheckboxFormField :: CSSFramework -> FormField -> Html -> Html
$sel:styledCheckboxFormField:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Html -> Html
styledCheckboxFormField, CSSFramework -> FormField -> Html -> Html
styledSelectFormField :: CSSFramework -> FormField -> Html -> Html
$sel:styledSelectFormField:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Html -> Html
styledSelectFormField, CSSFramework -> FormField -> Html -> Html
styledTextareaFormField :: CSSFramework -> FormField -> Html -> Html
$sel:styledTextareaFormField:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Html -> Html
styledTextareaFormField} FormField
formField =
                Html -> Html
formGroup Html
renderInner
                where
                    renderInner :: Html
renderInner = case Proxy "fieldType" -> FormField -> InputType
forall model (name :: Symbol) value.
(KnownSymbol name, HasField name model value) =>
Proxy name -> model -> value
get IsLabel "fieldType" (Proxy "fieldType")
Proxy "fieldType"
#fieldType FormField
formField of
                        InputType
TextInput -> CSSFramework -> Text -> FormField -> Html -> Html
styledTextFormField CSSFramework
cssFramework Text
"text" FormField
formField Html
validationResult
                        InputType
NumberInput -> CSSFramework -> Text -> FormField -> Html -> Html
styledTextFormField CSSFramework
cssFramework Text
"number" FormField
formField Html
validationResult
                        InputType
PasswordInput -> CSSFramework -> Text -> FormField -> Html -> Html
styledTextFormField CSSFramework
cssFramework Text
"password" FormField
formField Html
validationResult
                        InputType
ColorInput -> CSSFramework -> Text -> FormField -> Html -> Html
styledTextFormField CSSFramework
cssFramework Text
"color" FormField
formField Html
validationResult
                        InputType
EmailInput -> CSSFramework -> Text -> FormField -> Html -> Html
styledTextFormField CSSFramework
cssFramework Text
"email" FormField
formField Html
validationResult
                        InputType
DateInput -> CSSFramework -> Text -> FormField -> Html -> Html
styledTextFormField CSSFramework
cssFramework Text
"date" FormField
formField Html
validationResult
                        InputType
DateTimeInput -> CSSFramework -> Text -> FormField -> Html -> Html
styledTextFormField CSSFramework
cssFramework Text
"datetime-local" FormField
formField Html
validationResult
                        InputType
CheckboxInput -> CSSFramework -> FormField -> Html -> Html
styledCheckboxFormField CSSFramework
cssFramework FormField
formField Html
validationResult
                        InputType
HiddenInput -> CSSFramework -> Text -> FormField -> Html -> Html
styledTextFormField CSSFramework
cssFramework Text
"hidden" FormField
formField { $sel:disableLabel:FormField :: Bool
disableLabel = Bool
True, $sel:disableGroup:FormField :: Bool
disableGroup = Bool
True, $sel:disableValidationResult:FormField :: Bool
disableValidationResult = Bool
True } Html
validationResult
                        InputType
TextareaInput -> CSSFramework -> FormField -> Html -> Html
styledTextareaFormField CSSFramework
cssFramework FormField
formField Html
validationResult
                        SelectInput {} -> CSSFramework -> FormField -> Html -> Html
styledSelectFormField CSSFramework
cssFramework FormField
formField Html
validationResult
                        InputType
FileInput -> CSSFramework -> Text -> FormField -> Html -> Html
styledTextFormField CSSFramework
cssFramework Text
"file" FormField
formField Html
validationResult

                    validationResult :: Blaze.Html
                    validationResult :: Html
validationResult = Bool -> Html -> Html
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Proxy "disableValidationResult" -> FormField -> Bool
forall model (name :: Symbol) value.
(KnownSymbol name, HasField name model value) =>
Proxy name -> model -> value
get IsLabel "disableValidationResult" (Proxy "disableValidationResult")
Proxy "disableValidationResult"
#disableValidationResult FormField
formField) (CSSFramework -> FormField -> Html
styledValidationResult CSSFramework
cssFramework FormField
formField)

                    -- | Wraps the input inside a @<div class="form-group">...</div>@ (unless @disableGroup = True@)
                    formGroup :: Blaze.Html -> Blaze.Html
                    formGroup :: Html -> Html
formGroup Html
renderInner = case FormField
formField of
                        FormField { $sel:disableGroup:FormField :: FormField -> Bool
disableGroup = Bool
True } -> Html
renderInner
                        FormField { Text
$sel:fieldInputId:FormField :: FormField -> Text
fieldInputId :: Text
fieldInputId } -> CSSFramework -> Text -> Html -> Html
styledFormGroup CSSFramework
cssFramework Text
fieldInputId Html
renderInner


            styledFormGroup :: CSSFramework -> Text -> Blaze.Html -> Blaze.Html
            styledFormGroup :: CSSFramework -> Text -> Html -> Html
styledFormGroup cssFramework :: CSSFramework
cssFramework@CSSFramework {Text
styledFormGroupClass :: Text
$sel:styledFormGroupClass:CSSFramework :: CSSFramework -> Text
styledFormGroupClass} Text
fieldInputId Html
renderInner =
                [hsx|<div class={styledFormGroupClass} id={"form-group-" <> fieldInputId}>{renderInner}</div>|]

            styledCheckboxFormField :: CSSFramework -> FormField -> Blaze.Html -> Blaze.Html
            styledCheckboxFormField :: CSSFramework -> FormField -> Html -> Html
styledCheckboxFormField cssFramework :: CSSFramework
cssFramework@CSSFramework {CSSFramework -> FormField -> Text
styledInputInvalidClass :: CSSFramework -> FormField -> Text
$sel:styledInputInvalidClass:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Text
styledInputInvalidClass, CSSFramework -> FormField -> Html
styledFormFieldHelp :: CSSFramework -> FormField -> Html
$sel:styledFormFieldHelp:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Html
styledFormFieldHelp} formField :: FormField
formField@FormField {InputType
$sel:fieldType:FormField :: FormField -> InputType
fieldType :: InputType
fieldType, Text
$sel:fieldName:FormField :: FormField -> Text
fieldName :: Text
fieldName, Text
$sel:fieldLabel:FormField :: FormField -> Text
fieldLabel :: Text
fieldLabel, Text
$sel:fieldValue:FormField :: FormField -> Text
fieldValue :: Text
fieldValue, Text
fieldInputId :: Text
$sel:fieldInputId:FormField :: FormField -> Text
fieldInputId, Maybe Violation
$sel:validatorResult:FormField :: FormField -> Maybe Violation
validatorResult :: Maybe Violation
validatorResult, Text
$sel:fieldClass:FormField :: FormField -> Text
fieldClass :: Text
fieldClass, Bool
$sel:disabled:FormField :: FormField -> Bool
disabled :: Bool
disabled, Bool
disableLabel :: Bool
$sel:disableLabel:FormField :: FormField -> Bool
disableLabel, Bool
disableValidationResult :: Bool
$sel:disableValidationResult:FormField :: FormField -> Bool
disableValidationResult, [(Text, Text)]
$sel:additionalAttributes:FormField :: FormField -> [(Text, Text)]
additionalAttributes :: [(Text, Text)]
additionalAttributes, Text
$sel:labelClass:FormField :: FormField -> Text
labelClass :: Text
labelClass, Bool
$sel:required:FormField :: FormField -> Bool
required :: Bool
required, Bool
$sel:autofocus:FormField :: FormField -> Bool
autofocus :: Bool
autofocus } Html
validationResult = do
                [hsx|<div class="form-check">{element}</div>|]
                where
                    inputInvalidClass :: Text
inputInvalidClass = CSSFramework -> FormField -> Text
styledInputInvalidClass CSSFramework
cssFramework FormField
formField
                    helpText :: Html
helpText = CSSFramework -> FormField -> Html
styledFormFieldHelp CSSFramework
cssFramework FormField
formField

                    -- If the checkbox is checked off, the browser will not send the parameter as part of the form.
                    -- This will then make it impossible to set a field to False using a checkbox.
                    -- For that we add the "hidden" input type.
                    theInput :: Html
theInput = [hsx|
                                    <input
                                        type="checkbox"
                                        name={fieldName}
                                        class={classes ["form-check-input", (inputInvalidClass, isJust validatorResult), (fieldClass, not (null fieldClass))]}
                                        id={fieldInputId}
                                        checked={fieldValue == "yes"}
                                        required={required}
                                        disabled={disabled}
                                        autofocus={autofocus}
                                        {...additionalAttributes}
                                    />

                                    <input type="hidden" name={fieldName} value={inputValue False} />
                            |]


                    element :: Html
element = if Bool
disableLabel
                        then [hsx|<div>
                                    {theInput}
                                    {validationResult}
                                    {helpText}
                                </div>
                            |]
                        else [hsx|
                                {theInput}
                                <label
                                    class={classes [("form-check-label", labelClass == ""), (labelClass, labelClass /= "")]}
                                    for={fieldInputId}
                                >
                                    {fieldLabel}
                                </label>

                                {validationResult}
                                {helpText}
                            |]

            styledTextFormField :: CSSFramework -> Text -> FormField -> Blaze.Html -> Blaze.Html
            styledTextFormField :: CSSFramework -> Text -> FormField -> Html -> Html
styledTextFormField cssFramework :: CSSFramework
cssFramework@CSSFramework {CSSFramework -> FormField -> Text
styledInputClass :: CSSFramework -> FormField -> Text
$sel:styledInputClass:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Text
styledInputClass, CSSFramework -> FormField -> Text
styledInputInvalidClass :: CSSFramework -> FormField -> Text
$sel:styledInputInvalidClass:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Text
styledInputInvalidClass, CSSFramework -> FormField -> Html
styledFormFieldHelp :: CSSFramework -> FormField -> Html
$sel:styledFormFieldHelp:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Html
styledFormFieldHelp} Text
inputType formField :: FormField
formField@FormField {InputType
fieldType :: InputType
$sel:fieldType:FormField :: FormField -> InputType
fieldType, Text
fieldName :: Text
$sel:fieldName:FormField :: FormField -> Text
fieldName, Text
fieldLabel :: Text
$sel:fieldLabel:FormField :: FormField -> Text
fieldLabel, Text
fieldValue :: Text
$sel:fieldValue:FormField :: FormField -> Text
fieldValue, Text
fieldInputId :: Text
$sel:fieldInputId:FormField :: FormField -> Text
fieldInputId, Maybe Violation
validatorResult :: Maybe Violation
$sel:validatorResult:FormField :: FormField -> Maybe Violation
validatorResult, Text
fieldClass :: Text
$sel:fieldClass:FormField :: FormField -> Text
fieldClass, Bool
disabled :: Bool
$sel:disabled:FormField :: FormField -> Bool
disabled, Bool
disableLabel :: Bool
$sel:disableLabel:FormField :: FormField -> Bool
disableLabel, Bool
disableValidationResult :: Bool
$sel:disableValidationResult:FormField :: FormField -> Bool
disableValidationResult, [(Text, Text)]
additionalAttributes :: [(Text, Text)]
$sel:additionalAttributes:FormField :: FormField -> [(Text, Text)]
additionalAttributes, Text
labelClass :: Text
$sel:labelClass:FormField :: FormField -> Text
labelClass, Text
$sel:placeholder:FormField :: FormField -> Text
placeholder :: Text
placeholder, Bool
required :: Bool
$sel:required:FormField :: FormField -> Bool
required, Bool
autofocus :: Bool
$sel:autofocus:FormField :: FormField -> Bool
autofocus } Html
validationResult =
                [hsx|
                    {label}
                    <input
                        type={inputType}
                        name={fieldName}
                        placeholder={placeholder}
                        id={fieldInputId}
                        class={classes [inputClass, (inputInvalidClass, isJust validatorResult), (fieldClass, not (null fieldClass))]}
                        value={maybeValue}
                        required={required}
                        disabled={disabled}
                        autofocus={autofocus}
                        {...additionalAttributes}
                    />

                    {validationResult}
                    {helpText}
              |]
                where
                    label :: Html
label = Bool -> Html -> Html
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Bool
disableLabel Bool -> Bool -> Bool
|| Text -> Bool
forall mono. MonoFoldable mono => mono -> Bool
null Text
fieldLabel) [hsx|<label class={labelClass} for={fieldInputId}>{fieldLabel}</label>|]
                    inputClass :: (Text, Bool)
inputClass = (CSSFramework -> FormField -> Text
styledInputClass CSSFramework
cssFramework FormField
formField, Bool
True)
                    inputInvalidClass :: Text
inputInvalidClass = CSSFramework -> FormField -> Text
styledInputInvalidClass CSSFramework
cssFramework FormField
formField
                    helpText :: Html
helpText = CSSFramework -> FormField -> Html
styledFormFieldHelp CSSFramework
cssFramework FormField
formField
                    -- If there's no value, then we want to hide the "value" attribute.
                    maybeValue :: Maybe Text
maybeValue = if Text
fieldValue Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"" then Maybe Text
forall a. Maybe a
Nothing else Text -> Maybe Text
forall a. a -> Maybe a
Just Text
fieldValue

            styledSelectFormField :: CSSFramework -> FormField -> Blaze.Html -> Blaze.Html
            styledSelectFormField :: CSSFramework -> FormField -> Html -> Html
styledSelectFormField cssFramework :: CSSFramework
cssFramework@CSSFramework {CSSFramework -> FormField -> Text
styledInputClass :: CSSFramework -> FormField -> Text
$sel:styledInputClass:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Text
styledInputClass, CSSFramework -> FormField -> Text
styledInputInvalidClass :: CSSFramework -> FormField -> Text
$sel:styledInputInvalidClass:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Text
styledInputInvalidClass, CSSFramework -> FormField -> Html
styledFormFieldHelp :: CSSFramework -> FormField -> Html
$sel:styledFormFieldHelp:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Html
styledFormFieldHelp} formField :: FormField
formField@FormField {InputType
fieldType :: InputType
$sel:fieldType:FormField :: FormField -> InputType
fieldType, Text
fieldName :: Text
$sel:fieldName:FormField :: FormField -> Text
fieldName, Text
placeholder :: Text
$sel:placeholder:FormField :: FormField -> Text
placeholder, Text
fieldLabel :: Text
$sel:fieldLabel:FormField :: FormField -> Text
fieldLabel, Text
fieldValue :: Text
$sel:fieldValue:FormField :: FormField -> Text
fieldValue, Text
fieldInputId :: Text
$sel:fieldInputId:FormField :: FormField -> Text
fieldInputId, Maybe Violation
validatorResult :: Maybe Violation
$sel:validatorResult:FormField :: FormField -> Maybe Violation
validatorResult, Text
fieldClass :: Text
$sel:fieldClass:FormField :: FormField -> Text
fieldClass, Bool
disabled :: Bool
$sel:disabled:FormField :: FormField -> Bool
disabled, Bool
disableLabel :: Bool
$sel:disableLabel:FormField :: FormField -> Bool
disableLabel, Bool
disableValidationResult :: Bool
$sel:disableValidationResult:FormField :: FormField -> Bool
disableValidationResult, [(Text, Text)]
additionalAttributes :: [(Text, Text)]
$sel:additionalAttributes:FormField :: FormField -> [(Text, Text)]
additionalAttributes, Text
labelClass :: Text
$sel:labelClass:FormField :: FormField -> Text
labelClass, Bool
required :: Bool
$sel:required:FormField :: FormField -> Bool
required, Bool
autofocus :: Bool
$sel:autofocus:FormField :: FormField -> Bool
autofocus } Html
validationResult =
                [hsx|
                    {label}
                    <select
                        name={fieldName}
                        id={fieldInputId}
                        class={classes [inputClass, (inputInvalidClass, isJust validatorResult), (fieldClass, not (null fieldClass))]}
                        value={fieldValue}
                        disabled={disabled}
                        required={required}
                        autofocus={autofocus}
                        {...additionalAttributes}
                    >
                        <option selected={not isValueSelected} disabled={True}>{placeholder}</option>
                        {forEach (options fieldType) (getOption)}
                    </select>

                    {validationResult}
                    {helpText}
                |]
                where
                    label :: Html
label = Bool -> Html -> Html
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
disableLabel [hsx|<label class={labelClass} for={fieldInputId}>{fieldLabel}</label>|]
                    inputClass :: (Text, Bool)
inputClass = (CSSFramework -> FormField -> Text
styledInputClass CSSFramework
cssFramework FormField
formField, Bool
True)
                    inputInvalidClass :: Text
inputInvalidClass = CSSFramework -> FormField -> Text
styledInputInvalidClass CSSFramework
cssFramework FormField
formField
                    helpText :: Html
helpText = CSSFramework -> FormField -> Html
styledFormFieldHelp CSSFramework
cssFramework FormField
formField

                    isValueSelected :: Bool
isValueSelected = ((Text, Text) -> Bool) -> [(Text, Text)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (\(Text
_, Text
optionValue) -> Text
optionValue Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
fieldValue) (InputType -> [(Text, Text)]
options InputType
fieldType)

                    -- Get a single option.
                    getOption :: (Text, Text) -> Html
getOption (Text
optionLabel, Text
optionValue) = [hsx|
                        <option value={optionValue} selected={optionValue == fieldValue}>
                            {optionLabel}
                        </option>
                    |]

            styledTextareaFormField :: CSSFramework -> FormField -> Blaze.Html -> Blaze.Html
            styledTextareaFormField :: CSSFramework -> FormField -> Html -> Html
styledTextareaFormField cssFramework :: CSSFramework
cssFramework@CSSFramework {CSSFramework -> FormField -> Text
styledInputClass :: CSSFramework -> FormField -> Text
$sel:styledInputClass:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Text
styledInputClass, CSSFramework -> FormField -> Text
styledInputInvalidClass :: CSSFramework -> FormField -> Text
$sel:styledInputInvalidClass:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Text
styledInputInvalidClass, CSSFramework -> FormField -> Html
styledFormFieldHelp :: CSSFramework -> FormField -> Html
$sel:styledFormFieldHelp:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Html
styledFormFieldHelp} formField :: FormField
formField@FormField {InputType
fieldType :: InputType
$sel:fieldType:FormField :: FormField -> InputType
fieldType, Text
fieldName :: Text
$sel:fieldName:FormField :: FormField -> Text
fieldName, Text
fieldLabel :: Text
$sel:fieldLabel:FormField :: FormField -> Text
fieldLabel, Text
fieldValue :: Text
$sel:fieldValue:FormField :: FormField -> Text
fieldValue, Text
fieldInputId :: Text
$sel:fieldInputId:FormField :: FormField -> Text
fieldInputId, Maybe Violation
validatorResult :: Maybe Violation
$sel:validatorResult:FormField :: FormField -> Maybe Violation
validatorResult, Text
fieldClass :: Text
$sel:fieldClass:FormField :: FormField -> Text
fieldClass, Bool
disabled :: Bool
$sel:disabled:FormField :: FormField -> Bool
disabled, Bool
disableLabel :: Bool
$sel:disableLabel:FormField :: FormField -> Bool
disableLabel, Bool
disableValidationResult :: Bool
$sel:disableValidationResult:FormField :: FormField -> Bool
disableValidationResult, [(Text, Text)]
additionalAttributes :: [(Text, Text)]
$sel:additionalAttributes:FormField :: FormField -> [(Text, Text)]
additionalAttributes, Text
labelClass :: Text
$sel:labelClass:FormField :: FormField -> Text
labelClass, Text
placeholder :: Text
$sel:placeholder:FormField :: FormField -> Text
placeholder, Bool
required :: Bool
$sel:required:FormField :: FormField -> Bool
required, Bool
autofocus :: Bool
$sel:autofocus:FormField :: FormField -> Bool
autofocus } Html
validationResult =
                [hsx|
                    {label}
                    <textarea
                        name={fieldName}
                        placeholder={placeholder}
                        id={fieldInputId}
                        class={classes [inputClass, (inputInvalidClass, isJust validatorResult), (fieldClass, not (null fieldClass))]}
                        required={required}
                        disabled={disabled}
                        autofocus={autofocus}
                        {...additionalAttributes}
                    >{fieldValue}</textarea>{validationResult}{helpText}|]
                where
                    label :: Html
label = Bool -> Html -> Html
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Bool
disableLabel Bool -> Bool -> Bool
|| Text -> Bool
forall mono. MonoFoldable mono => mono -> Bool
null Text
fieldLabel) [hsx|<label class={labelClass} for={fieldInputId}>{fieldLabel}</label>|]
                    inputClass :: (Text, Bool)
inputClass = (CSSFramework -> FormField -> Text
styledInputClass CSSFramework
cssFramework FormField
formField, Bool
True)
                    inputInvalidClass :: Text
inputInvalidClass = CSSFramework -> FormField -> Text
styledInputInvalidClass CSSFramework
cssFramework FormField
formField
                    helpText :: Html
helpText = CSSFramework -> FormField -> Html
styledFormFieldHelp CSSFramework
cssFramework FormField
formField

            styledValidationResult :: CSSFramework -> FormField -> Blaze.Html
            styledValidationResult :: CSSFramework -> FormField -> Html
styledValidationResult CSSFramework
cssFramework formField :: FormField
formField@FormField { $sel:validatorResult:FormField :: FormField -> Maybe Violation
validatorResult = Just Violation
violation } =
                let
                    Text
className :: Text = Proxy "styledValidationResultClass" -> CSSFramework -> Text
forall model (name :: Symbol) value.
(KnownSymbol name, HasField name model value) =>
Proxy name -> model -> value
get IsLabel
  "styledValidationResultClass" (Proxy "styledValidationResultClass")
Proxy "styledValidationResultClass"
#styledValidationResultClass CSSFramework
cssFramework
                    message :: Html
message = case Violation
violation of
                        TextViolation Text
text -> [hsx|{text}|]
                        HtmlViolation Text
html -> Text -> Html
forall a. ToMarkup a => a -> Html
Blaze.preEscapedToHtml Text
html
                in
                    [hsx|<div class={className}>{message}</div>|]
            styledValidationResult CSSFramework
_ FormField
_ = Html
forall a. Monoid a => a
mempty

            styledValidationResultClass :: Text
styledValidationResultClass = Text
""

            styledSubmitButton :: model -> SubmitButton -> Html
styledSubmitButton model
cssFramework SubmitButton { Html
$sel:label:SubmitButton :: SubmitButton -> Html
label :: Html
label, Text
$sel:buttonClass:SubmitButton :: SubmitButton -> Text
buttonClass :: Text
buttonClass } =
                let Text
className :: Text = Proxy "styledSubmitButtonClass" -> model -> Text
forall model (name :: Symbol) value.
(KnownSymbol name, HasField name model value) =>
Proxy name -> model -> value
get IsLabel "styledSubmitButtonClass" (Proxy "styledSubmitButtonClass")
Proxy "styledSubmitButtonClass"
#styledSubmitButtonClass model
cssFramework
                in [hsx|<button class={classes [(className, True), (buttonClass, not (null buttonClass))]} type="submit">{label}</button>|]

            styledInputClass :: p -> p -> p
styledInputClass p
_ p
_ = p
""
            styledInputInvalidClass :: p -> p -> p
styledInputInvalidClass p
_ p
_ = p
"invalid"

            styledFormGroupClass :: Text
styledFormGroupClass = Text
""

            styledFormFieldHelp :: p -> FormField -> Html
styledFormFieldHelp p
_ FormField { $sel:helpText:FormField :: FormField -> Text
helpText = Text
"" } = Html
forall a. Monoid a => a
mempty
            styledFormFieldHelp p
_ FormField { Text
helpText :: Text
$sel:helpText:FormField :: FormField -> Text
helpText } = [hsx|<p>{helpText}</p>|]

            styledSubmitButtonClass :: Text
styledSubmitButtonClass = Text
""

            styledPagination :: CSSFramework -> PaginationView -> Blaze.Html
            styledPagination :: CSSFramework -> PaginationView -> Html
styledPagination CSSFramework
_ PaginationView
paginationView =
                [hsx|

                <div class="d-flex justify-content-md-center">
                    <nav aria-label="Page Navigator" class="mr-2">
                        <ul class="pagination">
                            {get #linkPrevious paginationView}
                            {get #pageDotDotItems paginationView}
                            {get #linkNext paginationView}
                        </ul>
                    </nav>

                    <div class="form-row">
                        <div class="col-auto mr-2">
                            <select class="custom-select" id="maxItemsSelect" onchange="window.location.href = this.options[this.selectedIndex].dataset.url">
                                {get #itemsPerPageSelector paginationView}
                            </select>
                        </div>
                    </div>

                </div>
                |]

            styledPaginationPageLink :: CSSFramework -> Pagination -> ByteString -> Int -> Blaze.Html
            styledPaginationPageLink :: CSSFramework -> Pagination -> ByteString -> Int -> Html
styledPaginationPageLink CSSFramework
_ pagination :: Pagination
pagination@Pagination {Int
$sel:currentPage:Pagination :: Pagination -> Int
currentPage :: Int
currentPage} ByteString
pageUrl Int
pageNumber =
                let
                    linkClass :: Text
linkClass = [(Text, Bool)] -> Text
classes [(Text, Bool)
"page-item", (Text
"active", Int
pageNumber Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
currentPage)]
                in
                    [hsx|<li class={linkClass}><a class="page-link" href={pageUrl}>{show pageNumber}</a></li>|]


            styledPaginationDotDot :: CSSFramework -> Pagination -> Blaze.Html
            styledPaginationDotDot :: CSSFramework -> Pagination -> Html
styledPaginationDotDot CSSFramework
_ Pagination
_ =
                [hsx|<li class="page-item"><a class="page-link">…</a></li>|]

            styledPaginationItemsPerPageSelector :: CSSFramework -> Pagination -> (Int -> ByteString) -> Blaze.Html
            styledPaginationItemsPerPageSelector :: CSSFramework -> Pagination -> (Int -> ByteString) -> Html
styledPaginationItemsPerPageSelector CSSFramework
_ pagination :: Pagination
pagination@Pagination {Int
$sel:pageSize:Pagination :: Pagination -> Int
pageSize :: Int
pageSize} Int -> ByteString
itemsPerPageUrl =
                let
                    oneOption :: Int -> Blaze.Html
                    oneOption :: Int -> Html
oneOption Int
n = [hsx|<option value={show n} selected={n == pageSize} data-url={itemsPerPageUrl n}>{n} items per page</option>|]
                in
                    [hsx|{forEach [10,20,50,100,200] oneOption}|]

            styledPaginationLinkPrevious :: CSSFramework -> Pagination -> ByteString -> Blaze.Html
            styledPaginationLinkPrevious :: CSSFramework -> Pagination -> ByteString -> Html
styledPaginationLinkPrevious CSSFramework
_ pagination :: Pagination
pagination@Pagination {Int
currentPage :: Int
$sel:currentPage:Pagination :: Pagination -> Int
currentPage} ByteString
pageUrl =
                let
                    prevClass :: Text
prevClass = [(Text, Bool)] -> Text
classes [(Text, Bool)
"page-item", (Text
"disabled", Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Pagination -> Bool
hasPreviousPage Pagination
pagination)]
                    url :: ByteString
url = if Pagination -> Bool
hasPreviousPage Pagination
pagination then ByteString
pageUrl else ByteString
"#"
                in
                    [hsx|
                        <li class={prevClass}>
                            <a class="page-link" href={url} aria-label="Previous">
                                <span aria-hidden="true">&laquo;</span>
                                <span class="sr-only">Previous</span>
                            </a>
                        </li>
                    |]

            styledPaginationLinkNext :: CSSFramework -> Pagination -> ByteString -> Blaze.Html
            styledPaginationLinkNext :: CSSFramework -> Pagination -> ByteString -> Html
styledPaginationLinkNext CSSFramework
_ pagination :: Pagination
pagination@Pagination {Int
currentPage :: Int
$sel:currentPage:Pagination :: Pagination -> Int
currentPage} ByteString
pageUrl =
                let
                    nextClass :: Text
nextClass = [(Text, Bool)] -> Text
classes [(Text, Bool)
"page-item", (Text
"disabled", Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Pagination -> Bool
hasNextPage Pagination
pagination)]
                    url :: ByteString
url = if Pagination -> Bool
hasNextPage Pagination
pagination then ByteString
pageUrl else ByteString
"#"
                in
                    [hsx|
                        <li class={nextClass}>
                            <a class="page-link" href={url} aria-label="Next">
                                <span aria-hidden="true">&raquo;</span>
                                <span class="sr-only">Next</span>
                            </a>
                        </li>
                    |]

            styledBreadcrumb :: CSSFramework -> [BreadcrumbItem]-> BreadcrumbsView -> Blaze.Html
            styledBreadcrumb :: CSSFramework -> [BreadcrumbItem] -> BreadcrumbsView -> Html
styledBreadcrumb CSSFramework
_ [BreadcrumbItem]
_ BreadcrumbsView
breadcrumbsView = [hsx|
                <nav>
                    <ol class="breadcrumb">
                        {get #breadcrumbItems breadcrumbsView}

                    </ol>
                </nav>
            |]


            styledBreadcrumbItem :: CSSFramework -> [ BreadcrumbItem ]-> BreadcrumbItem -> Bool -> Blaze.Html
            styledBreadcrumbItem :: CSSFramework -> [BreadcrumbItem] -> BreadcrumbItem -> Bool -> Html
styledBreadcrumbItem CSSFramework
_ [BreadcrumbItem]
breadcrumbItems breadcrumbItem :: BreadcrumbItem
breadcrumbItem@BreadcrumbItem {Html
$sel:breadcrumbLabel:BreadcrumbItem :: BreadcrumbItem -> Html
breadcrumbLabel :: Html
breadcrumbLabel, Maybe Text
$sel:url:BreadcrumbItem :: BreadcrumbItem -> Maybe Text
url :: Maybe Text
url} Bool
isLast =
                let
                    breadcrumbsClasses :: Text
breadcrumbsClasses = [(Text, Bool)] -> Text
classes [(Text, Bool)
"breadcrumb-item", (Text
"active", Bool
isLast)]
                in
                case Maybe Text
url of
                    Maybe Text
Nothing ->  [hsx|<li class={breadcrumbsClasses}>{breadcrumbLabel}</li>|]
                    Just Text
url -> [hsx|<li class={breadcrumbsClasses}><a href={url}>{breadcrumbLabel}</a></li>|]



bootstrap :: CSSFramework
bootstrap :: CSSFramework
bootstrap = CSSFramework
forall a. Default a => a
def
    { CSSFramework -> FlashMessage -> Html
forall p. p -> FlashMessage -> Html
styledFlashMessage :: forall p. p -> FlashMessage -> Html
$sel:styledFlashMessage:CSSFramework :: CSSFramework -> FlashMessage -> Html
styledFlashMessage
    , Text
styledSubmitButtonClass :: Text
$sel:styledSubmitButtonClass:CSSFramework :: Text
styledSubmitButtonClass
    , Text
styledFormGroupClass :: Text
$sel:styledFormGroupClass:CSSFramework :: Text
styledFormGroupClass
    , CSSFramework -> FormField -> Html
forall p. p -> FormField -> Html
styledFormFieldHelp :: forall p. p -> FormField -> Html
$sel:styledFormFieldHelp:CSSFramework :: CSSFramework -> FormField -> Html
styledFormFieldHelp
    , CSSFramework -> FormField -> Text
forall p p. IsString p => p -> FormField -> p
styledInputClass :: forall p p. IsString p => p -> FormField -> p
$sel:styledInputClass:CSSFramework :: CSSFramework -> FormField -> Text
styledInputClass
    , CSSFramework -> FormField -> Text
forall p p p. IsString p => p -> p -> p
styledInputInvalidClass :: forall p p p. IsString p => p -> p -> p
$sel:styledInputInvalidClass:CSSFramework :: CSSFramework -> FormField -> Text
styledInputInvalidClass
    , Text
styledValidationResultClass :: Text
$sel:styledValidationResultClass:CSSFramework :: Text
styledValidationResultClass
    }
    where
        styledFlashMessage :: p -> FlashMessage -> Html
styledFlashMessage p
_ (SuccessFlashMessage Text
message) = [hsx|<div class="alert alert-success">{message}</div>|]
        styledFlashMessage p
_ (ErrorFlashMessage Text
message) = [hsx|<div class="alert alert-danger">{message}</div>|]

        styledInputClass :: p -> FormField -> p
styledInputClass p
_ FormField { $sel:fieldType:FormField :: FormField -> InputType
fieldType = InputType
FileInput } = p
"form-control-file"
        styledInputClass p
_ FormField {} = p
"form-control"
        styledInputInvalidClass :: p -> p -> p
styledInputInvalidClass p
_ p
_ = p
"is-invalid"

        styledFormFieldHelp :: p -> FormField -> Html
styledFormFieldHelp p
_ FormField { $sel:helpText:FormField :: FormField -> Text
helpText = Text
"" } = Html
forall a. Monoid a => a
mempty
        styledFormFieldHelp p
_ FormField { Text
helpText :: Text
$sel:helpText:FormField :: FormField -> Text
helpText } = [hsx|<small class="form-text text-muted">{helpText}</small>|]

        styledFormGroupClass :: Text
styledFormGroupClass = Text
"form-group"

        styledValidationResultClass :: Text
styledValidationResultClass = Text
"invalid-feedback"

        styledSubmitButtonClass :: Text
styledSubmitButtonClass = Text
"btn btn-primary"

tailwind :: CSSFramework
tailwind :: CSSFramework
tailwind = CSSFramework
forall a. Default a => a
def
    { CSSFramework -> FlashMessage -> Html
forall p. p -> FlashMessage -> Html
styledFlashMessage :: forall p. p -> FlashMessage -> Html
$sel:styledFlashMessage:CSSFramework :: CSSFramework -> FlashMessage -> Html
styledFlashMessage
    , CSSFramework -> Text -> FormField -> Html -> Html
styledTextFormField :: CSSFramework -> Text -> FormField -> Html -> Html
$sel:styledTextFormField:CSSFramework :: CSSFramework -> Text -> FormField -> Html -> Html
styledTextFormField
    , CSSFramework -> FormField -> Html -> Html
styledTextareaFormField :: CSSFramework -> FormField -> Html -> Html
$sel:styledTextareaFormField:CSSFramework :: CSSFramework -> FormField -> Html -> Html
styledTextareaFormField
    , CSSFramework -> FormField -> Html -> Html
styledCheckboxFormField :: CSSFramework -> FormField -> Html -> Html
$sel:styledCheckboxFormField:CSSFramework :: CSSFramework -> FormField -> Html -> Html
styledCheckboxFormField
    , CSSFramework -> FormField -> Html -> Html
styledSelectFormField :: CSSFramework -> FormField -> Html -> Html
$sel:styledSelectFormField:CSSFramework :: CSSFramework -> FormField -> Html -> Html
styledSelectFormField
    , Text
styledSubmitButtonClass :: Text
$sel:styledSubmitButtonClass:CSSFramework :: Text
styledSubmitButtonClass
    , Text
styledFormGroupClass :: Text
$sel:styledFormGroupClass:CSSFramework :: Text
styledFormGroupClass
    , CSSFramework -> FormField -> Html
forall p. p -> FormField -> Html
styledFormFieldHelp :: forall p. p -> FormField -> Html
$sel:styledFormFieldHelp:CSSFramework :: CSSFramework -> FormField -> Html
styledFormFieldHelp
    , CSSFramework -> FormField -> Text
forall p p. IsString p => p -> FormField -> p
styledInputClass :: forall p p. IsString p => p -> FormField -> p
$sel:styledInputClass:CSSFramework :: CSSFramework -> FormField -> Text
styledInputClass
    , CSSFramework -> FormField -> Text
forall p p p. IsString p => p -> p -> p
styledInputInvalidClass :: forall p p p. IsString p => p -> p -> p
$sel:styledInputInvalidClass:CSSFramework :: CSSFramework -> FormField -> Text
styledInputInvalidClass
    , Text
styledValidationResultClass :: Text
$sel:styledValidationResultClass:CSSFramework :: Text
styledValidationResultClass
    , CSSFramework -> PaginationView -> Html
styledPagination :: CSSFramework -> PaginationView -> Html
$sel:styledPagination:CSSFramework :: CSSFramework -> PaginationView -> Html
styledPagination
    , CSSFramework -> Pagination -> ByteString -> Html
styledPaginationLinkPrevious :: CSSFramework -> Pagination -> ByteString -> Html
$sel:styledPaginationLinkPrevious:CSSFramework :: CSSFramework -> Pagination -> ByteString -> Html
styledPaginationLinkPrevious
    , CSSFramework -> Pagination -> ByteString -> Html
styledPaginationLinkNext :: CSSFramework -> Pagination -> ByteString -> Html
$sel:styledPaginationLinkNext:CSSFramework :: CSSFramework -> Pagination -> ByteString -> Html
styledPaginationLinkNext
    , CSSFramework -> Pagination -> ByteString -> Int -> Html
styledPaginationPageLink :: CSSFramework -> Pagination -> ByteString -> Int -> Html
$sel:styledPaginationPageLink:CSSFramework :: CSSFramework -> Pagination -> ByteString -> Int -> Html
styledPaginationPageLink
    , CSSFramework -> Pagination -> Html
styledPaginationDotDot :: CSSFramework -> Pagination -> Html
$sel:styledPaginationDotDot:CSSFramework :: CSSFramework -> Pagination -> Html
styledPaginationDotDot
    , CSSFramework -> Pagination -> (Int -> ByteString) -> Html
styledPaginationItemsPerPageSelector :: CSSFramework -> Pagination -> (Int -> ByteString) -> Html
$sel:styledPaginationItemsPerPageSelector:CSSFramework :: CSSFramework -> Pagination -> (Int -> ByteString) -> Html
styledPaginationItemsPerPageSelector
    , CSSFramework -> [BreadcrumbItem] -> BreadcrumbsView -> Html
styledBreadcrumb :: CSSFramework -> [BreadcrumbItem] -> BreadcrumbsView -> Html
$sel:styledBreadcrumb:CSSFramework :: CSSFramework -> [BreadcrumbItem] -> BreadcrumbsView -> Html
styledBreadcrumb
    , CSSFramework -> [BreadcrumbItem] -> BreadcrumbItem -> Bool -> Html
styledBreadcrumbItem :: CSSFramework -> [BreadcrumbItem] -> BreadcrumbItem -> Bool -> Html
$sel:styledBreadcrumbItem:CSSFramework :: CSSFramework -> [BreadcrumbItem] -> BreadcrumbItem -> Bool -> Html
styledBreadcrumbItem
    }
    where
        styledFlashMessage :: p -> FlashMessage -> Html
styledFlashMessage p
_ (SuccessFlashMessage Text
message) = [hsx|<div class="bg-green-100 border border-green-500 text-green-900 px-4 py-3 rounded relative">{message}</div>|]
        styledFlashMessage p
_ (ErrorFlashMessage Text
message) = [hsx|<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative">{message}</div>|]

        styledCheckboxFormField :: CSSFramework -> FormField -> Blaze.Html -> Blaze.Html
        styledCheckboxFormField :: CSSFramework -> FormField -> Html -> Html
styledCheckboxFormField cssFramework :: CSSFramework
cssFramework@CSSFramework {CSSFramework -> FormField -> Text
styledInputInvalidClass :: CSSFramework -> FormField -> Text
$sel:styledInputInvalidClass:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Text
styledInputInvalidClass, CSSFramework -> FormField -> Html
styledFormFieldHelp :: CSSFramework -> FormField -> Html
$sel:styledFormFieldHelp:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Html
styledFormFieldHelp} formField :: FormField
formField@FormField {InputType
fieldType :: InputType
$sel:fieldType:FormField :: FormField -> InputType
fieldType, Text
fieldName :: Text
$sel:fieldName:FormField :: FormField -> Text
fieldName, Text
fieldLabel :: Text
$sel:fieldLabel:FormField :: FormField -> Text
fieldLabel, Text
fieldValue :: Text
$sel:fieldValue:FormField :: FormField -> Text
fieldValue, Text
fieldInputId :: Text
$sel:fieldInputId:FormField :: FormField -> Text
fieldInputId, Maybe Violation
validatorResult :: Maybe Violation
$sel:validatorResult:FormField :: FormField -> Maybe Violation
validatorResult, Text
fieldClass :: Text
$sel:fieldClass:FormField :: FormField -> Text
fieldClass, Bool
disabled :: Bool
$sel:disabled:FormField :: FormField -> Bool
disabled, Bool
disableLabel :: Bool
$sel:disableLabel:FormField :: FormField -> Bool
disableLabel, Bool
disableValidationResult :: Bool
$sel:disableValidationResult:FormField :: FormField -> Bool
disableValidationResult, [(Text, Text)]
additionalAttributes :: [(Text, Text)]
$sel:additionalAttributes:FormField :: FormField -> [(Text, Text)]
additionalAttributes, Text
labelClass :: Text
$sel:labelClass:FormField :: FormField -> Text
labelClass, Bool
required :: Bool
$sel:required:FormField :: FormField -> Bool
required, Bool
autofocus :: Bool
$sel:autofocus:FormField :: FormField -> Bool
autofocus } Html
validationResult = do
            [hsx|<div class="form-check">{element}</div>|]
            where
                inputInvalidClass :: Text
inputInvalidClass = CSSFramework -> FormField -> Text
styledInputInvalidClass CSSFramework
cssFramework FormField
formField
                helpText :: Html
helpText = CSSFramework -> FormField -> Html
styledFormFieldHelp CSSFramework
cssFramework FormField
formField

                theInput :: Html
theInput = [hsx|
                            <div>
                                <input
                                    type="checkbox"
                                    name={fieldName}
                                    class={classes ["form-check-input", (inputInvalidClass, isJust validatorResult), (fieldClass, not (null fieldClass))]}
                                    id={fieldInputId}
                                    checked={fieldValue == "yes"}
                                    required={required}
                                    disabled={disabled}
                                    autofocus={autofocus}
                                    {...additionalAttributes}
                                />

                                <input type="hidden" name={fieldName} value={inputValue False} />
                            </div>
                        |]


                element :: Html
element = if Bool
disableLabel
                    then [hsx|<div class="flex flex-row space-x-2">
                                {theInput}
                                <div class="flex flex-col space-y-2">
                                    {validationResult}
                                    {helpText}
                                </div>
                            </div>
                        |]
                    else [hsx|
                            <div class="flex flex-row space-x-2">
                                {theInput}
                                <div class="flex flex-col">
                                    <label
                                        class={classes ["font-medium text-gray-700", ("form-check-label", labelClass == ""), (labelClass, labelClass /= "")]}
                                        for={fieldInputId}
                                    >
                                        {fieldLabel}
                                    </label>

                                    {validationResult}
                                    {helpText}
                                </div>
                            </div>
                        |]

        styledTextFormField :: CSSFramework -> Text -> FormField -> Blaze.Html -> Blaze.Html
        styledTextFormField :: CSSFramework -> Text -> FormField -> Html -> Html
styledTextFormField cssFramework :: CSSFramework
cssFramework@CSSFramework {CSSFramework -> FormField -> Text
styledInputClass :: CSSFramework -> FormField -> Text
$sel:styledInputClass:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Text
styledInputClass, CSSFramework -> FormField -> Text
styledInputInvalidClass :: CSSFramework -> FormField -> Text
$sel:styledInputInvalidClass:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Text
styledInputInvalidClass, CSSFramework -> FormField -> Html
styledFormFieldHelp :: CSSFramework -> FormField -> Html
$sel:styledFormFieldHelp:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Html
styledFormFieldHelp} Text
inputType formField :: FormField
formField@FormField {InputType
fieldType :: InputType
$sel:fieldType:FormField :: FormField -> InputType
fieldType, Text
fieldName :: Text
$sel:fieldName:FormField :: FormField -> Text
fieldName, Text
fieldLabel :: Text
$sel:fieldLabel:FormField :: FormField -> Text
fieldLabel, Text
fieldValue :: Text
$sel:fieldValue:FormField :: FormField -> Text
fieldValue, Text
fieldInputId :: Text
$sel:fieldInputId:FormField :: FormField -> Text
fieldInputId, Maybe Violation
validatorResult :: Maybe Violation
$sel:validatorResult:FormField :: FormField -> Maybe Violation
validatorResult, Text
fieldClass :: Text
$sel:fieldClass:FormField :: FormField -> Text
fieldClass, Bool
disabled :: Bool
$sel:disabled:FormField :: FormField -> Bool
disabled, Bool
disableLabel :: Bool
$sel:disableLabel:FormField :: FormField -> Bool
disableLabel, Bool
disableValidationResult :: Bool
$sel:disableValidationResult:FormField :: FormField -> Bool
disableValidationResult, [(Text, Text)]
additionalAttributes :: [(Text, Text)]
$sel:additionalAttributes:FormField :: FormField -> [(Text, Text)]
additionalAttributes, Text
labelClass :: Text
$sel:labelClass:FormField :: FormField -> Text
labelClass, Text
placeholder :: Text
$sel:placeholder:FormField :: FormField -> Text
placeholder, Bool
required :: Bool
$sel:required:FormField :: FormField -> Bool
required, Bool
autofocus :: Bool
$sel:autofocus:FormField :: FormField -> Bool
autofocus } Html
validationResult =
            [hsx|
                {label}
                <input
                    type={inputType}
                    name={fieldName}
                    placeholder={placeholder}
                    id={fieldInputId}
                    class={classes [inputClass, (inputInvalidClass, isJust validatorResult), (fieldClass, not (null fieldClass))]}
                    value={maybeValue}
                    required={required}
                    disabled={disabled}
                    autofocus={autofocus}
                    {...additionalAttributes}
                />

                {validationResult}
                {helpText}
            |]
            where
                twLabelClass :: Text
twLabelClass = Text
"font-medium text-gray-700" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
labelClass
                label :: Html
label = Bool -> Html -> Html
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Bool
disableLabel Bool -> Bool -> Bool
|| Text -> Bool
forall mono. MonoFoldable mono => mono -> Bool
null Text
fieldLabel) [hsx|<label class={twLabelClass} for={fieldInputId}>{fieldLabel}</label>|]
                inputClass :: (Text, Bool)
inputClass = (CSSFramework -> FormField -> Text
styledInputClass CSSFramework
cssFramework FormField
formField, Bool
True)
                inputInvalidClass :: Text
inputInvalidClass = CSSFramework -> FormField -> Text
styledInputInvalidClass CSSFramework
cssFramework FormField
formField
                helpText :: Html
helpText = CSSFramework -> FormField -> Html
styledFormFieldHelp CSSFramework
cssFramework FormField
formField
                -- If there's no value, then we want to hide the "value" attribute.
                maybeValue :: Maybe Text
maybeValue = if Text
fieldValue Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"" then Maybe Text
forall a. Maybe a
Nothing else Text -> Maybe Text
forall a. a -> Maybe a
Just Text
fieldValue


        styledTextareaFormField :: CSSFramework -> FormField -> Blaze.Html -> Blaze.Html
        styledTextareaFormField :: CSSFramework -> FormField -> Html -> Html
styledTextareaFormField cssFramework :: CSSFramework
cssFramework@CSSFramework {CSSFramework -> FormField -> Text
styledInputClass :: CSSFramework -> FormField -> Text
$sel:styledInputClass:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Text
styledInputClass, CSSFramework -> FormField -> Text
styledInputInvalidClass :: CSSFramework -> FormField -> Text
$sel:styledInputInvalidClass:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Text
styledInputInvalidClass, CSSFramework -> FormField -> Html
styledFormFieldHelp :: CSSFramework -> FormField -> Html
$sel:styledFormFieldHelp:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Html
styledFormFieldHelp} formField :: FormField
formField@FormField {InputType
fieldType :: InputType
$sel:fieldType:FormField :: FormField -> InputType
fieldType, Text
fieldName :: Text
$sel:fieldName:FormField :: FormField -> Text
fieldName, Text
fieldLabel :: Text
$sel:fieldLabel:FormField :: FormField -> Text
fieldLabel, Text
fieldValue :: Text
$sel:fieldValue:FormField :: FormField -> Text
fieldValue, Text
fieldInputId :: Text
$sel:fieldInputId:FormField :: FormField -> Text
fieldInputId, Maybe Violation
validatorResult :: Maybe Violation
$sel:validatorResult:FormField :: FormField -> Maybe Violation
validatorResult, Text
fieldClass :: Text
$sel:fieldClass:FormField :: FormField -> Text
fieldClass, Bool
disabled :: Bool
$sel:disabled:FormField :: FormField -> Bool
disabled, Bool
disableLabel :: Bool
$sel:disableLabel:FormField :: FormField -> Bool
disableLabel, Bool
disableValidationResult :: Bool
$sel:disableValidationResult:FormField :: FormField -> Bool
disableValidationResult, [(Text, Text)]
additionalAttributes :: [(Text, Text)]
$sel:additionalAttributes:FormField :: FormField -> [(Text, Text)]
additionalAttributes, Text
labelClass :: Text
$sel:labelClass:FormField :: FormField -> Text
labelClass, Text
placeholder :: Text
$sel:placeholder:FormField :: FormField -> Text
placeholder, Bool
required :: Bool
$sel:required:FormField :: FormField -> Bool
required, Bool
autofocus :: Bool
$sel:autofocus:FormField :: FormField -> Bool
autofocus } Html
validationResult =
            [hsx|
                {label}
                <textarea
                    name={fieldName}
                    placeholder={placeholder}
                    id={fieldInputId}
                    class={classes [inputClass, (inputInvalidClass, isJust validatorResult), (fieldClass, not (null fieldClass))]}
                    required={required}
                    disabled={disabled}
                    autofocus={autofocus}
                    {...additionalAttributes}
                >{fieldValue}</textarea>{validationResult}{helpText}
            |]
            where
                twLabelClass :: Text
twLabelClass = [(Text, Bool)] -> Text
classes [(Text, Bool)
"font-medium text-gray-700", (Text
labelClass, Bool -> Bool
not (Text -> Bool
forall mono. MonoFoldable mono => mono -> Bool
null Text
labelClass))]
                label :: Html
label = Bool -> Html -> Html
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Bool
disableLabel Bool -> Bool -> Bool
|| Text -> Bool
forall mono. MonoFoldable mono => mono -> Bool
null Text
fieldLabel) [hsx|<label class={twLabelClass} for={fieldInputId}>{fieldLabel}</label>|]
                inputClass :: (Text, Bool)
inputClass = (CSSFramework -> FormField -> Text
styledInputClass CSSFramework
cssFramework FormField
formField, Bool
True)
                inputInvalidClass :: Text
inputInvalidClass = CSSFramework -> FormField -> Text
styledInputInvalidClass CSSFramework
cssFramework FormField
formField
                helpText :: Html
helpText = CSSFramework -> FormField -> Html
styledFormFieldHelp CSSFramework
cssFramework FormField
formField


        styledSelectFormField :: CSSFramework -> FormField -> Blaze.Html -> Blaze.Html
        styledSelectFormField :: CSSFramework -> FormField -> Html -> Html
styledSelectFormField cssFramework :: CSSFramework
cssFramework@CSSFramework {CSSFramework -> FormField -> Text
styledInputClass :: CSSFramework -> FormField -> Text
$sel:styledInputClass:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Text
styledInputClass, CSSFramework -> FormField -> Text
styledInputInvalidClass :: CSSFramework -> FormField -> Text
$sel:styledInputInvalidClass:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Text
styledInputInvalidClass, CSSFramework -> FormField -> Html
styledFormFieldHelp :: CSSFramework -> FormField -> Html
$sel:styledFormFieldHelp:CSSFramework :: CSSFramework -> CSSFramework -> FormField -> Html
styledFormFieldHelp} formField :: FormField
formField@FormField {InputType
fieldType :: InputType
$sel:fieldType:FormField :: FormField -> InputType
fieldType, Text
fieldName :: Text
$sel:fieldName:FormField :: FormField -> Text
fieldName, Text
placeholder :: Text
$sel:placeholder:FormField :: FormField -> Text
placeholder, Text
fieldLabel :: Text
$sel:fieldLabel:FormField :: FormField -> Text
fieldLabel, Text
fieldValue :: Text
$sel:fieldValue:FormField :: FormField -> Text
fieldValue, Text
fieldInputId :: Text
$sel:fieldInputId:FormField :: FormField -> Text
fieldInputId, Maybe Violation
validatorResult :: Maybe Violation
$sel:validatorResult:FormField :: FormField -> Maybe Violation
validatorResult, Text
fieldClass :: Text
$sel:fieldClass:FormField :: FormField -> Text
fieldClass, Bool
disabled :: Bool
$sel:disabled:FormField :: FormField -> Bool
disabled, Bool
disableLabel :: Bool
$sel:disableLabel:FormField :: FormField -> Bool
disableLabel, Bool
disableValidationResult :: Bool
$sel:disableValidationResult:FormField :: FormField -> Bool
disableValidationResult, [(Text, Text)]
additionalAttributes :: [(Text, Text)]
$sel:additionalAttributes:FormField :: FormField -> [(Text, Text)]
additionalAttributes, Text
labelClass :: Text
$sel:labelClass:FormField :: FormField -> Text
labelClass, Bool
required :: Bool
$sel:required:FormField :: FormField -> Bool
required, Bool
autofocus :: Bool
$sel:autofocus:FormField :: FormField -> Bool
autofocus } Html
validationResult =
            [hsx|
                {label}
                <select
                    name={fieldName}
                    id={fieldInputId}
                    class={classes [inputClass, (inputInvalidClass, isJust validatorResult), (fieldClass, not (null fieldClass))]}
                    value={fieldValue}
                    disabled={disabled}
                    required={required}
                    autofocus={autofocus}
                    {...additionalAttributes}
                >
                    <option selected={not isValueSelected} disabled={True}>{placeholder}</option>
                    {forEach (options fieldType) (getOption)}
                </select>

                {validationResult}
                {helpText}
            |]
            where
                twLabelClass :: Text
twLabelClass = Text
"font-medium text-gray-700" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
labelClass
                label :: Html
label = Bool -> Html -> Html
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
disableLabel [hsx|<label class={twLabelClass} for={fieldInputId}>{fieldLabel}</label>|]
                inputClass :: (Text, Bool)
inputClass = (CSSFramework -> FormField -> Text
styledInputClass CSSFramework
cssFramework FormField
formField, Bool
True)
                inputInvalidClass :: Text
inputInvalidClass = CSSFramework -> FormField -> Text
styledInputInvalidClass CSSFramework
cssFramework FormField
formField
                helpText :: Html
helpText = CSSFramework -> FormField -> Html
styledFormFieldHelp CSSFramework
cssFramework FormField
formField

                isValueSelected :: Bool
isValueSelected = ((Text, Text) -> Bool) -> [(Text, Text)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (\(Text
_, Text
optionValue) -> Text
optionValue Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
fieldValue) (InputType -> [(Text, Text)]
options InputType
fieldType)

                -- Get a single option.
                getOption :: (Text, Text) -> Html
getOption (Text
optionLabel, Text
optionValue) = [hsx|
                    <option value={optionValue} selected={optionValue == fieldValue}>
                        {optionLabel}
                    </option>
                |]


        styledInputClass :: p -> FormField -> p
styledInputClass p
_ FormField {} = p
"focus:ring-blue-500 focus:border-blue-500 block w-full border-gray-300 rounded-md"
        styledInputInvalidClass :: p -> p -> p
styledInputInvalidClass p
_ p
_ = p
"is-invalid"

        styledSubmitButtonClass :: Text
styledSubmitButtonClass = Text
"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"

        styledFormFieldHelp :: p -> FormField -> Html
styledFormFieldHelp p
_ FormField { $sel:helpText:FormField :: FormField -> Text
helpText = Text
"" } = Html
forall a. Monoid a => a
mempty
        styledFormFieldHelp p
_ FormField { Text
helpText :: Text
$sel:helpText:FormField :: FormField -> Text
helpText } = [hsx|<p class="text-gray-600 text-xs italic">{helpText}</p>|]

        styledFormGroupClass :: Text
styledFormGroupClass = Text
"flex flex-col my-6 space-y-2"

        styledValidationResultClass :: Text
styledValidationResultClass = Text
"text-red-500 text-xs italic"

        styledPagination :: CSSFramework -> PaginationView -> Blaze.Html
        styledPagination :: CSSFramework -> PaginationView -> Html
styledPagination CSSFramework
_ paginationView :: PaginationView
paginationView@PaginationView {Int -> ByteString
$sel:pageUrl:PaginationView :: PaginationView -> Int -> ByteString
pageUrl :: Int -> ByteString
pageUrl, Pagination
pagination :: Pagination
$sel:pagination:PaginationView :: PaginationView -> Pagination
pagination} =
            let
                currentPage :: Int
currentPage = Proxy "currentPage" -> Pagination -> Int
forall model (name :: Symbol) value.
(KnownSymbol name, HasField name model value) =>
Proxy name -> model -> value
get IsLabel "currentPage" (Proxy "currentPage")
Proxy "currentPage"
#currentPage Pagination
pagination

                previousPageUrl :: ByteString
previousPageUrl = if Pagination -> Bool
hasPreviousPage Pagination
pagination then Int -> ByteString
pageUrl (Int -> ByteString) -> Int -> ByteString
forall a b. (a -> b) -> a -> b
$ Int
currentPage Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1 else ByteString
"#"
                nextPageUrl :: ByteString
nextPageUrl = if Pagination -> Bool
hasNextPage Pagination
pagination then Int -> ByteString
pageUrl (Int -> ByteString) -> Int -> ByteString
forall a b. (a -> b) -> a -> b
$ Int
currentPage Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 else ByteString
"#"

                defaultClass :: (Text, Bool)
defaultClass = (Text, Bool)
"relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50"
                previousClass :: Text
previousClass = [(Text, Bool)] -> Text
classes
                    [ (Text, Bool)
defaultClass
                    , (Text
"disabled", Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Pagination -> Bool
hasPreviousPage Pagination
pagination)
                    ]
                nextClass :: Text
nextClass = [(Text, Bool)] -> Text
classes
                    [ (Text, Bool)
defaultClass
                    , (Text
"disabled", Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Pagination -> Bool
hasNextPage Pagination
pagination)
                    ]

                previousMobileOnly :: Html
previousMobileOnly =
                    [hsx|
                        <a href={previousPageUrl} class={previousClass}>
                            Previous
                        </a>
                    |]

                nextMobileOnly :: Html
nextMobileOnly =
                    [hsx|
                        <a href={nextPageUrl} class={nextClass}>
                            Next
                        </a>
                    |]

            in
            [hsx|
                <div class="bg-white px-4 py-3 flex items-center justify-between border-t border-gray-200 sm:px-6">
                    <div class="flex-1 flex justify-between sm:hidden">
                        {previousMobileOnly}
                        {nextMobileOnly}
                    </div>
                    <div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
                        <div class="text-sm text-gray-700">
                            <select class="px-4 py-3" id="maxItemsSelect" onchange="window.location.href = this.options[this.selectedIndex].dataset.url">
                                {get #itemsPerPageSelector paginationView}
                            </select>
                        </div>
                        <div>
                        <nav class="relative z-0 inline-flex rounded-md shadow-sm -space-x-px" aria-label="Pagination">
                            {get #linkPrevious paginationView}

                            {get #pageDotDotItems paginationView}

                            {get #linkNext paginationView}
                        </nav>
                        </div>
                    </div>
                </div>
            |]

        styledPaginationLinkPrevious :: CSSFramework -> Pagination -> ByteString -> Blaze.Html
        styledPaginationLinkPrevious :: CSSFramework -> Pagination -> ByteString -> Html
styledPaginationLinkPrevious CSSFramework
_ pagination :: Pagination
pagination@Pagination {Int
currentPage :: Int
$sel:currentPage:Pagination :: Pagination -> Int
currentPage} ByteString
pageUrl =
            let
                prevClass :: Text
prevClass = [(Text, Bool)] -> Text
classes
                    [ (Text, Bool)
"relative inline-flex items-center px-2 py-2 rounded-l-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50"
                    , (Text
"disabled", Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Pagination -> Bool
hasPreviousPage Pagination
pagination)
                    ]

                url :: ByteString
url = if Pagination -> Bool
hasPreviousPage Pagination
pagination then ByteString
pageUrl else ByteString
"#"

            in
                [hsx|
                    <a href={url} class={prevClass}>
                        <span class="sr-only">Previous</span>
                        <!-- Heroicon name: solid/chevron-left -->
                        <svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
                            <path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
                        </svg>
                    </a>
                |]

        styledPaginationLinkNext :: CSSFramework -> Pagination -> ByteString -> Blaze.Html
        styledPaginationLinkNext :: CSSFramework -> Pagination -> ByteString -> Html
styledPaginationLinkNext CSSFramework
_ pagination :: Pagination
pagination@Pagination {Int
currentPage :: Int
$sel:currentPage:Pagination :: Pagination -> Int
currentPage} ByteString
pageUrl =
            let
                nextClass :: Text
nextClass = [(Text, Bool)] -> Text
classes
                    [ (Text, Bool)
"relative inline-flex items-center px-2 py-2 rounded-r-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50"
                    , (Text
"disabled", Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Pagination -> Bool
hasNextPage Pagination
pagination)
                    ]

                url :: ByteString
url = if Pagination -> Bool
hasNextPage Pagination
pagination then ByteString
pageUrl else ByteString
"#"
            in
                [hsx|
                    <a href={url} class={nextClass}>
                        <span class="sr-only">Next</span>
                        <!-- Heroicon name: solid/chevron-right -->
                        <svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
                            <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
                        </svg>
                    </a>

                |]

        styledPaginationPageLink :: CSSFramework -> Pagination -> ByteString -> Int -> Blaze.Html
        styledPaginationPageLink :: CSSFramework -> Pagination -> ByteString -> Int -> Html
styledPaginationPageLink CSSFramework
_ pagination :: Pagination
pagination@Pagination {Int
currentPage :: Int
$sel:currentPage:Pagination :: Pagination -> Int
currentPage} ByteString
pageUrl Int
pageNumber =
            let
                linkClass :: Text
linkClass = [(Text, Bool)] -> Text
classes
                    [ (Text, Bool)
"relative inline-flex items-center px-4 py-2 border text-sm font-medium"
                    -- Current page
                    , (Text
"z-10 bg-blue-50 border-blue-500 text-blue-600", Int
pageNumber Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
currentPage)
                    -- Not current page
                    , (Text
"bg-white border-gray-300 text-gray-500 hover:bg-gray-50", Int
pageNumber Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
currentPage)
                    ]
            in
                [hsx|
                    <a href={pageUrl} aria-current={pageNumber == currentPage} class={linkClass}>
                        {show pageNumber}
                    </a>
                |]


        styledPaginationDotDot :: CSSFramework -> Pagination -> Blaze.Html
        styledPaginationDotDot :: CSSFramework -> Pagination -> Html
styledPaginationDotDot CSSFramework
_ Pagination
_ =
            [hsx|
                <span class="relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-700">
                    ...
                </span>
        |]


        styledPaginationItemsPerPageSelector :: CSSFramework -> Pagination -> (Int -> ByteString) -> Blaze.Html
        styledPaginationItemsPerPageSelector :: CSSFramework -> Pagination -> (Int -> ByteString) -> Html
styledPaginationItemsPerPageSelector CSSFramework
_ pagination :: Pagination
pagination@Pagination {Int
pageSize :: Int
$sel:pageSize:Pagination :: Pagination -> Int
pageSize} Int -> ByteString
itemsPerPageUrl =
            let
                oneOption :: Int -> Blaze.Html
                oneOption :: Int -> Html
oneOption Int
n = [hsx|<option value={show n} selected={n == pageSize} data-url={itemsPerPageUrl n}>{n} items per page</option>|]
            in
                [hsx|{forEach [10,20,50,100,200] oneOption}|]


        styledBreadcrumb :: CSSFramework -> [BreadcrumbItem]-> BreadcrumbsView -> Blaze.Html
        styledBreadcrumb :: CSSFramework -> [BreadcrumbItem] -> BreadcrumbsView -> Html
styledBreadcrumb CSSFramework
_ [BreadcrumbItem]
_ BreadcrumbsView
breadcrumbsView = [hsx|
            <nav class="breadcrumbs bg-white my-4" aria-label="Breadcrumb">
                <ol class="flex items-center space-x-2" role="list">
                    {get #breadcrumbItems breadcrumbsView}
                </ol>
            </nav>
        |]


        styledBreadcrumbItem :: CSSFramework -> [ BreadcrumbItem ]-> BreadcrumbItem -> Bool -> Blaze.Html
        styledBreadcrumbItem :: CSSFramework -> [BreadcrumbItem] -> BreadcrumbItem -> Bool -> Html
styledBreadcrumbItem CSSFramework
_ [BreadcrumbItem]
breadcrumbItems breadcrumbItem :: BreadcrumbItem
breadcrumbItem@BreadcrumbItem {Html
breadcrumbLabel :: Html
$sel:breadcrumbLabel:BreadcrumbItem :: BreadcrumbItem -> Html
breadcrumbLabel, Maybe Text
url :: Maybe Text
$sel:url:BreadcrumbItem :: BreadcrumbItem -> Maybe Text
url} Bool
isLast =
            let
                breadcrumbsClasses :: Text
breadcrumbsClasses = [(Text, Bool)] -> Text
classes [(Text, Bool)
"flex flex-row space-x-2 text-gray-600 items-center", (Text
"active", Bool
isLast)]

                -- Show chevron if item isn't the active one (i.e. the last one).
                chevronRight :: Html
chevronRight = Bool -> Html -> Html
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
isLast [hsx|
                <!-- heroicons.com chevron-right -->
                <svg xmlns="http://www.w3.org/2000/svg" class="flex-shrink-0 h-4 w-4 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
                </svg>
                |]
            in
            case Maybe Text
url of
                Maybe Text
Nothing ->  [hsx|
                    <li class={breadcrumbsClasses}>
                        {breadcrumbLabel}
                        {chevronRight}
                    </li>
                |]
                Just Text
url -> [hsx|
                    <li class={breadcrumbsClasses}>
                        <a class="hover:text-gray-700" href={url}>{breadcrumbLabel}</a>
                        {chevronRight}
                    </li>
                    |]