{- |
Module      : Htmx.Lucid.Head
Description : Utilities for including HTMX in the html head tag

This module defines utilities for installing HTMX and HTMX extensions
via the head tag in your html document
<https://htmx.org/docs/#installing>
-}
module Htmx.Lucid.Head (
    useHtmx,
    useHtmxVersion,
    useHtmxExtension,
    useHtmxExtensionV,
    useHtmxExtensions,
    useHtmxExtensionsV,
    recommendedVersion,
    htmxSrc,
    htmxSrcWithSemVer,
    htmxExtSrc,
) where

import Data.Foldable (forM_)
import Data.Text (Text, pack)
import GHC.Natural (Natural)
import Htmx.Extension
import Htmx.Render
import Lucid (Html, HtmlT, script_, src_)
import Lucid.Base (Attribute, makeAttribute)

-- | Place in your template after @useHtmx@, but before where the extension is used via @hxExt_@
-- NOTE: This uses 'recommendedVersion' as the version section of the URL
useHtmxExtension :: (Monad m) => HtmxExtension -> HtmlT m ()
useHtmxExtension :: forall (m :: * -> *). Monad m => HtmxExtension -> HtmlT m ()
useHtmxExtension = (Natural, Natural, Natural) -> HtmxExtension -> HtmlT m ()
forall (m :: * -> *).
Monad m =>
(Natural, Natural, Natural) -> HtmxExtension -> HtmlT m ()
useHtmxExtensionV (Natural, Natural, Natural)
recommendedVersion

-- | Same as 'useHtmxExt' but lets you choose the version url
useHtmxExtensionV ::
    (Monad m) => (Natural, Natural, Natural) -> HtmxExtension -> HtmlT m ()
useHtmxExtensionV :: forall (m :: * -> *).
Monad m =>
(Natural, Natural, Natural) -> HtmxExtension -> HtmlT m ()
useHtmxExtensionV (Natural, Natural, Natural)
v HtmxExtension
ext = [Attribute] -> Html () -> HtmlT m ()
forall arg result. TermRaw arg result => arg -> result
script_ [Text -> Attribute
src_ (Text -> Attribute) -> Text -> Attribute
forall a b. (a -> b) -> a -> b
$ (Natural, Natural, Natural) -> Text -> Text
htmxExtSrc (Natural, Natural, Natural)
v (HtmxExtension -> Text
forall a. Render a => a -> Text
render HtmxExtension
ext)] (Html ()
"" :: Html ())

-- | A typesafe version of 'useHtmxExtension' based on the "included" extensions
-- that the htmx codebase is tested against
-- NOTE: This uses 'recommendedVersion' as the version section of the URL
useHtmxExtensions :: (Monad m) => [HtmxExtension] -> HtmlT m ()
useHtmxExtensions :: forall (m :: * -> *). Monad m => [HtmxExtension] -> HtmlT m ()
useHtmxExtensions [HtmxExtension]
exts = [HtmxExtension] -> (HtmxExtension -> HtmlT m ()) -> HtmlT m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [HtmxExtension]
exts HtmxExtension -> HtmlT m ()
forall (m :: * -> *). Monad m => HtmxExtension -> HtmlT m ()
useHtmxExtension

-- | Same as 'useHtmxExts' but with a versioned url
useHtmxExtensionsV ::
    (Monad m) => (Natural, Natural, Natural) -> [HtmxExtension] -> HtmlT m ()
useHtmxExtensionsV :: forall (m :: * -> *).
Monad m =>
(Natural, Natural, Natural) -> [HtmxExtension] -> HtmlT m ()
useHtmxExtensionsV (Natural, Natural, Natural)
v [HtmxExtension]
exts = [HtmxExtension] -> (HtmxExtension -> HtmlT m ()) -> HtmlT m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [HtmxExtension]
exts ((Natural, Natural, Natural) -> HtmxExtension -> HtmlT m ()
forall (m :: * -> *).
Monad m =>
(Natural, Natural, Natural) -> HtmxExtension -> HtmlT m ()
useHtmxExtensionV (Natural, Natural, Natural)
v)

-- | Place in your @head_@ tag to use htmx attributes in your lucid template
useHtmx :: (Monad m) => HtmlT m ()
useHtmx :: forall (m :: * -> *). Monad m => HtmlT m ()
useHtmx = (Natural, Natural, Natural) -> HtmlT m ()
forall (m :: * -> *).
Monad m =>
(Natural, Natural, Natural) -> HtmlT m ()
useHtmxVersion (Natural, Natural, Natural)
recommendedVersion

-- | Choose the version of htmx to use using a 3-tuple representing semantic versioning
useHtmxVersion :: (Monad m) => (Natural, Natural, Natural) -> HtmlT m ()
useHtmxVersion :: forall (m :: * -> *).
Monad m =>
(Natural, Natural, Natural) -> HtmlT m ()
useHtmxVersion (Natural, Natural, Natural)
semVer = [Attribute] -> Html () -> HtmlT m ()
forall arg result. TermRaw arg result => arg -> result
script_ [Text -> Attribute
src_ (Text -> Attribute) -> Text -> Attribute
forall a b. (a -> b) -> a -> b
$ (Natural, Natural, Natural) -> Text
htmxSrcWithSemVer (Natural, Natural, Natural)
semVer] (Html ()
"" :: Html ())

-- | This is the recommended version of htmx for using this library
-- (lucid-htmx). It is the version of the documentation that the implementation
-- is based off of.
recommendedVersion :: (Natural, Natural, Natural)
recommendedVersion :: (Natural, Natural, Natural)
recommendedVersion = (Natural
2, Natural
0, Natural
0)

htmxSrc :: Text
htmxSrc :: Text
htmxSrc = Text
"https://unpkg.com/htmx.org"

showT :: (Show a) => a -> Text
showT :: forall a. Show a => a -> Text
showT = String -> Text
pack (String -> Text) -> (a -> String) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show

showSemVer :: (Natural, Natural, Natural) -> Text
showSemVer :: (Natural, Natural, Natural) -> Text
showSemVer (Natural
major, Natural
minor, Natural
patch) =
    Text
"@"
        Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Natural -> Text
forall a. Show a => a -> Text
showT Natural
major
        Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"."
        Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Natural -> Text
forall a. Show a => a -> Text
showT Natural
minor
        Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"."
        Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Natural -> Text
forall a. Show a => a -> Text
showT Natural
patch

htmxSrcWithSemVer :: (Natural, Natural, Natural) -> Text
htmxSrcWithSemVer :: (Natural, Natural, Natural) -> Text
htmxSrcWithSemVer (Natural, Natural, Natural)
ver =
    Text
htmxSrc Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (Natural, Natural, Natural) -> Text
showSemVer (Natural, Natural, Natural)
ver

htmxExtSrc :: (Natural, Natural, Natural) -> Text -> Text
htmxExtSrc :: (Natural, Natural, Natural) -> Text -> Text
htmxExtSrc (Natural, Natural, Natural)
ver Text
ext =
    Text
"https://unpkg.com/htmx-ext-"
        Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
ext
        Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (Natural, Natural, Natural) -> Text
showSemVer (Natural, Natural, Natural)
ver
        Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/"
        Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
ext
        Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
".js"