website/frontend/src/Layouts/Navbar.elm

917 lines
26 KiB
Elm
Raw Normal View History

2024-11-11 03:57:54 -06:00
module Layouts.Navbar exposing (Model, Msg, Props, layout)
2024-12-11 02:38:42 -06:00
import Config.Data.Identity exposing (pageNames)
2024-12-11 03:48:49 -06:00
import Config.Helpers.Format
2024-12-09 19:53:09 -06:00
exposing
( paragraphFontSize
, paragraphSpacing
)
2024-12-27 01:30:21 -06:00
import Config.Style.Colour.Helpers exposing (colourTheme)
2024-12-09 19:53:09 -06:00
import Config.Style.Fonts exposing (spartanFont)
2024-12-11 02:38:42 -06:00
import Config.Style.Glow exposing (glowDeepDarkGreyNavbar)
2024-12-11 03:48:49 -06:00
import Config.Style.Icons.Icons
2024-12-09 19:53:09 -06:00
exposing
2024-12-11 02:38:42 -06:00
( circleDots
, circleX
, contact
2024-12-09 19:53:09 -06:00
, debate
, discord
, donate
, gitlab
, home
, hyperBlog
, interviews
2024-12-23 03:15:35 -06:00
, leaving
2024-12-27 01:30:21 -06:00
, line
2024-12-11 02:38:42 -06:00
, lock
2024-12-09 19:53:09 -06:00
, mastodon
, nutriDex
, services
, twitter
, upRootLarge
, upRootMedium
, upRootSmall
2024-12-19 01:43:02 -06:00
, video
2024-12-09 19:53:09 -06:00
)
2024-12-11 03:48:49 -06:00
import Config.Style.Icons.Types as TySvg exposing (..)
2024-12-09 22:11:15 -06:00
import Config.Style.Transitions
exposing
( hoverFontLightOrange
2024-12-11 02:38:42 -06:00
, specialNavbarTransition
, transitionStyleFast
2024-12-09 22:11:15 -06:00
, transitionStyleMedium
2024-12-11 02:38:42 -06:00
, transitionStyleSlow
2024-12-09 22:11:15 -06:00
)
2024-11-11 03:57:54 -06:00
import Effect exposing (Effect)
import Element as E exposing (..)
2024-12-09 19:53:09 -06:00
import Element.Background as B
import Element.Border as D
2024-12-08 21:16:04 -06:00
import Element.Events as Events
2024-11-11 03:57:54 -06:00
import Element.Font as F
import Element.Region exposing (description)
import Html exposing (Html)
2024-12-09 22:11:15 -06:00
import Html.Attributes as H
exposing
( class
, style
)
2024-11-11 03:57:54 -06:00
import Layout exposing (Layout)
2024-12-11 02:38:42 -06:00
import Maybe.Extra
2024-11-11 03:57:54 -06:00
import Route exposing (Route)
2024-12-11 02:38:42 -06:00
import Route.Path as Path
2024-11-11 03:57:54 -06:00
import Shared
2024-12-11 02:38:42 -06:00
import Shared.Msg
import Svg.Attributes as SvgAttr
2024-11-11 03:57:54 -06:00
import View exposing (View)
type alias Props =
2024-12-06 22:03:24 -06:00
{}
2024-11-11 03:57:54 -06:00
layout : Props -> Shared.Model -> Route () -> Layout () Model Msg contentMsg
2024-12-11 02:38:42 -06:00
layout _ s r =
2024-11-11 03:57:54 -06:00
Layout.new
2024-12-11 02:38:42 -06:00
{ init = init s
2024-11-11 03:57:54 -06:00
, update = update
2024-12-11 02:38:42 -06:00
, view = view r s
, subscriptions = \_ -> Sub.none
2024-11-11 03:57:54 -06:00
}
-- MODEL
type alias Model =
2024-12-11 02:38:42 -06:00
{ isNavbarExpanded : Bool }
2024-11-11 03:57:54 -06:00
2024-12-11 02:38:42 -06:00
init : Shared.Model -> () -> ( Model, Effect.Effect Msg )
init shared _ =
( { isNavbarExpanded = shared.isNavbarExpanded }
2024-11-11 03:57:54 -06:00
, Effect.none
)
-- UPDATE
type Msg
= ReplaceMe
2024-12-11 02:38:42 -06:00
| ToggleNavbarExpansion
| ToggleLanguage
2024-11-11 03:57:54 -06:00
2024-12-11 02:38:42 -06:00
update : Msg -> Model -> ( Model, Effect.Effect Msg )
2024-11-11 03:57:54 -06:00
update msg model =
case msg of
ReplaceMe ->
( model
, Effect.none
)
2024-12-11 02:38:42 -06:00
ToggleLanguage ->
( model
, Effect.toggleLanguage
)
ToggleNavbarExpansion ->
( { model | isNavbarExpanded = not model.isNavbarExpanded }
, Effect.toggleNavbarExpansion
)
2024-11-11 03:57:54 -06:00
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
2024-12-11 02:38:42 -06:00
view : Route () -> Shared.Model -> { toContentMsg : Msg -> contentMsg, content : View.View contentMsg, model : Model } -> View.View contentMsg
view route shared { toContentMsg, content, model } =
2024-12-07 15:43:26 -06:00
{ title = "uRN :: " ++ content.title
2024-12-11 02:38:42 -06:00
, attributes =
[ B.color colourTheme.backgroundDarkGrey
, F.color colourTheme.textLightGrey
, F.family [ spartanFont ]
2024-12-08 02:18:36 -06:00
, height fill
]
2024-12-11 02:38:42 -06:00
, element =
navbarContainer
{ route = route
, sharedModel = shared
, model = model
, contentMessage = toContentMsg ToggleNavbarExpansion
, languageSelectorMessage = toContentMsg ToggleLanguage
, content = content
}
(case shared.device.class of
Phone ->
topbar
2024-12-08 02:18:36 -06:00
2024-12-11 02:38:42 -06:00
Tablet ->
topbar
2024-12-08 02:18:36 -06:00
_ ->
2024-12-11 02:38:42 -06:00
sidebar
2024-12-08 02:18:36 -06:00
)
2024-12-11 02:38:42 -06:00
}
2024-12-08 02:18:36 -06:00
2024-12-11 02:38:42 -06:00
languageSelector : contentMsg -> Element contentMsg
languageSelector m =
el
[ alignRight
, Events.onClick m
2024-12-08 02:18:36 -06:00
]
2024-12-11 02:38:42 -06:00
<|
none
2024-12-08 02:18:36 -06:00
2024-12-11 02:38:42 -06:00
navbarContainer : NavbarInput contentMsg -> NavbarMaker contentMsg -> Element contentMsg
navbarContainer input maker =
el
[ height fill
, inFront <| maker input
, inFront <| languageSelector input.languageSelectorMessage
, paddingEach <|
(\( top, left ) ->
{ top = top
, right = 0
, bottom = 0
, left = left
}
)
(case input.sharedModel.device.class of
Phone ->
( barReservedRegion.topbar, 0 )
2024-12-08 02:18:36 -06:00
2024-12-11 02:38:42 -06:00
Tablet ->
( barReservedRegion.topbar, 0 )
2024-12-08 02:18:36 -06:00
2024-12-11 02:38:42 -06:00
_ ->
( 0, barReservedRegion.sidebar )
)
, width fill
]
<|
el
[ height fill
, width fill
, scrollbarY
2024-12-27 01:30:21 -06:00
, E.htmlAttribute (H.id "scroll-container")
2024-12-11 02:38:42 -06:00
]
input.content.element
2024-12-08 02:18:36 -06:00
2024-12-11 02:38:42 -06:00
barReservedRegion : { sidebar : number, topbar : number }
barReservedRegion =
{ sidebar = 70
, topbar = 60
}
2024-12-08 02:18:36 -06:00
2024-12-11 02:38:42 -06:00
bar : NavbarInput contentMsg -> NavbarLogoMaker contentMsg -> List (Attribute contentMsg) -> Element contentMsg
bar input logo attr =
2024-12-08 02:18:36 -06:00
column
2024-12-11 02:38:42 -06:00
([ B.color colourTheme.backgroundDarkGrey
, transitionStyleMedium
]
++ attr
)
<|
[ logo input
, items input
, footerItems input
2024-12-08 02:18:36 -06:00
]
2024-12-11 02:38:42 -06:00
topbar : NavbarInput contentMsg -> Element contentMsg
topbar input =
bar input
topbarLogo
[ height <|
px <|
if input.model.isNavbarExpanded then
input.sharedModel.height
else
barReservedRegion.topbar
, width fill
, D.widthEach
{ bottom = 1
, top = 0
, left = 0
, right = 0
}
, D.color colourTheme.textDarkOrange
2024-12-08 03:04:37 -06:00
]
2024-12-11 02:38:42 -06:00
topbarLogo : NavbarInput contentMsg -> Element contentMsg
topbarLogo input =
2024-12-27 01:30:21 -06:00
let
svgFormat =
{ elementAttributes =
[ centerX
, centerY
, Events.onClick input.contentMessage
, transitionStyleSlow
]
, sharedModel = input.sharedModel
, svgAttributes = [ SvgAttr.width "30" ]
}
in
2024-12-11 02:38:42 -06:00
row
([ height <| px barReservedRegion.topbar
, transitionStyleMedium
, width fill
]
++ (if input.model.isNavbarExpanded then
[ B.color colourTheme.backgroundDarkGrey ]
else
[]
)
)
<|
[ link
[ pointer ]
{ url = Path.toString Path.Home_
, label =
2024-12-22 19:42:23 -06:00
el [ paddingXY 10 0, width <| px 250 ] <| html upRootLarge
2024-12-11 02:38:42 -06:00
}
2024-12-08 03:04:37 -06:00
, el
2024-12-11 02:38:42 -06:00
[ height <| px 50
, width <| px 40
, alignRight
2024-12-27 01:30:21 -06:00
, centerY
, moveUp 5
2024-11-11 18:57:51 -06:00
]
2024-12-11 02:38:42 -06:00
<|
2024-12-27 01:30:21 -06:00
-- (if input.model.isNavbarExpanded then
column [ centerY ]
[ line
(if input.model.isNavbarExpanded then
{ elementAttributes =
[ centerX
, centerY
, moveDown 13
, rotate (degrees 45)
, Events.onClick input.contentMessage
, transitionStyleSlow
]
, sharedModel = input.sharedModel
, svgAttributes = [ SvgAttr.width "30" ]
}
else
{ elementAttributes =
[ centerX
, centerY
, Events.onClick input.contentMessage
, transitionStyleSlow
]
, sharedModel = input.sharedModel
, svgAttributes = [ SvgAttr.width "30" ]
}
)
, line
(if input.model.isNavbarExpanded then
{ elementAttributes =
[ centerX
, centerY
, moveUp 22
, transparent True
, Events.onClick input.contentMessage
, transitionStyleSlow
]
, sharedModel = input.sharedModel
, svgAttributes = [ SvgAttr.width "30" ]
}
else
{ elementAttributes =
[ centerX
, centerY
, moveUp 22
, Events.onClick input.contentMessage
, transitionStyleSlow
]
, sharedModel = input.sharedModel
, svgAttributes = [ SvgAttr.width "30" ]
}
)
, line
(if input.model.isNavbarExpanded then
{ elementAttributes =
[ centerX
, centerY
, rotate (degrees -45)
, moveUp 56
, Events.onClick input.contentMessage
, transitionStyleSlow
]
, sharedModel = input.sharedModel
, svgAttributes = [ SvgAttr.width "30" ]
}
else
{ elementAttributes =
[ centerX
, centerY
, moveUp 44
, Events.onClick input.contentMessage
, transitionStyleSlow
]
, sharedModel = input.sharedModel
, svgAttributes = [ SvgAttr.width "30" ]
}
)
]
2024-12-08 02:18:36 -06:00
]
2024-12-11 02:38:42 -06:00
sidebar : NavbarInput contentMsg -> Element contentMsg
sidebar input =
bar input
sidebarLogo
[ Events.onMouseEnter <| input.contentMessage
, Events.onMouseLeave <| input.contentMessage
2024-12-08 02:18:36 -06:00
, height fill
2024-12-11 02:38:42 -06:00
, htmlAttribute <| style "overflow" "hidden"
, htmlAttribute <| style "z-index" "2"
, D.widthEach
{ bottom = 0
, top = 0
, left = 0
, right = 3
2024-12-08 02:18:36 -06:00
}
2024-12-11 03:48:49 -06:00
, glowDeepDarkGreyNavbar
2024-12-11 02:38:42 -06:00
, D.color colourTheme.textDarkOrange
, if input.model.isNavbarExpanded then
width <| px 225
else
width <| px barReservedRegion.sidebar
2024-12-08 02:18:36 -06:00
]
2024-12-11 02:38:42 -06:00
sidebarLogo : NavbarInput contentMsg -> Element contentMsg
sidebarLogo input =
let
logo : Element msg
logo =
el
[ width <| px 40
, transitionStyleMedium
, if input.model.isNavbarExpanded then
htmlAttribute (style "transform" "rotate(360deg)")
else
htmlAttribute (style "transform" "rotate(0deg)")
]
<|
html upRootSmall
text : Element msg
text =
el
([ centerY
, transitionStyleMedium
, width <| px 145
]
++ (if input.model.isNavbarExpanded then
[]
else
[ transparent True ]
)
)
<|
html upRootLarge
in
2024-12-08 02:18:36 -06:00
el
2024-12-11 02:38:42 -06:00
[ transitionStyleMedium
, height <| px 60
, width fill
]
<|
el
[ alignRight
, centerY
]
<|
el
[ transitionStyleMedium
, onLeft text
, paddingEach
{ top = 0
, right = 12
, bottom = 0
, left = 12
}
, width fill
]
logo
items : NavbarInput contentMsg -> Element contentMsg
items input =
let
navbarUnfucker : List (Attr () msg)
navbarUnfucker =
[ transparent True
, htmlAttribute (style "position" "absolute")
, htmlAttribute (style "z-index" "-10")
, htmlAttribute (style "opacity" "0")
, htmlAttribute (style "pointer-events" "none")
, htmlAttribute (style "visibility" "hidden")
]
in
2024-12-11 02:38:42 -06:00
column
2024-12-22 04:36:03 -06:00
[ height fill
2024-12-11 02:38:42 -06:00
, width fill
2024-12-08 02:18:36 -06:00
]
2024-12-11 02:38:42 -06:00
<|
List.map
(\x ->
el
([ width fill
, transitionStyleMedium
]
++ (if input.model.isNavbarExpanded then
case input.sharedModel.device.class of
_ ->
[ transparent False ]
else
case input.sharedModel.device.class of
Phone ->
navbarUnfucker
Tablet ->
navbarUnfucker
_ ->
[ transparent False ]
)
)
<|
makeItem input
{ icon = x.icon
, isCurrent = x.isCurrent
, isNewTabLink = x.isNewTabLink
, isSubscriberOnly = x.isSubscriberOnly
, name = x.name
, sharedModel = input.sharedModel
, url = x.url
}
2024-12-11 02:38:42 -06:00
)
[ { icon = home
, isCurrent = input.route.path == Path.Home_
, isNewTabLink = False
, isSubscriberOnly = False
, name = String.toUpper pageNames.pageHome
, url = Path.toString Path.Home_
}
, { icon = services
, isCurrent = input.route.path == Path.Services
, isNewTabLink = False
, isSubscriberOnly = False
, name = String.toUpper pageNames.pageServices
, url = Path.toString Path.Services
}
, { icon = hyperBlog
2024-12-16 00:12:23 -06:00
, isCurrent = input.route.path == Path.Blog
2024-12-11 02:38:42 -06:00
, isNewTabLink = False
, isSubscriberOnly = False
, name = String.toUpper pageNames.pageHyperBlog
2024-12-16 00:12:23 -06:00
, url = Path.toString Path.Blog
2024-12-11 02:38:42 -06:00
}
2024-12-19 01:43:02 -06:00
, { icon = video
, isCurrent = False
, isNewTabLink = True
, isSubscriberOnly = False
, name = String.toUpper "Video"
, url = "https://video.uprootnutrition.com"
}
2024-12-11 02:38:42 -06:00
, { icon = debate
, isCurrent = input.route.path == Path.Debate
, isNewTabLink = False
, isSubscriberOnly = False
, name = String.toUpper pageNames.pageDebate
, url = Path.toString Path.Debate
}
, { icon = nutriDex
, isCurrent = input.route.path == Path.Nutridex
, isNewTabLink = False
, isSubscriberOnly = False
, name = String.toUpper pageNames.pageNutriDex
, url = Path.toString Path.Nutridex
}
, { icon = interviews
, isCurrent = input.route.path == Path.Interviews
, isNewTabLink = False
, isSubscriberOnly = False
, name = String.toUpper pageNames.pageInterviews
, url = Path.toString Path.Interviews
}
, { icon = donate
, isCurrent = input.route.path == Path.Donate
, isNewTabLink = False
, isSubscriberOnly = False
, name = String.toUpper pageNames.pageDonate
, url = Path.toString Path.Donate
}
, { icon = contact
, isCurrent = input.route.path == Path.Contact
, isNewTabLink = False
, isSubscriberOnly = False
, name = String.toUpper pageNames.pageContact
, url = Path.toString Path.Contact
}
]
2024-12-08 02:18:36 -06:00
makeItemLogic : NavbarInput contentMsg -> RowInput contentMsg -> Element contentMsg
makeItemLogic input route =
if input.model.isNavbarExpanded then
case input.sharedModel.device.class of
_ ->
makeItem input route
else
case input.sharedModel.device.class of
Phone ->
el [] none
Tablet ->
el [] none
_ ->
makeItem input route
2024-12-11 02:38:42 -06:00
makeItem : NavbarInput contentMsg -> RowInput contentMsg -> Element contentMsg
makeItem input route =
(if route.isNewTabLink then
newTabLink
2024-12-08 21:16:04 -06:00
2024-12-11 02:38:42 -06:00
else
link
)
[ width fill ]
{ label =
2024-12-08 02:18:36 -06:00
row
2024-12-11 02:38:42 -06:00
([ mouseOver
(if route.isCurrent then
[]
else
[ B.gradient
{ angle = 1.57
, steps =
case input.sharedModel.device.class of
Phone ->
[ colourTheme.backgroundLightGrey
, colourTheme.backgroundDarkGrey
, colourTheme.backgroundDarkGrey
]
Tablet ->
[ colourTheme.backgroundLightGrey
, colourTheme.backgroundDarkGrey
, colourTheme.backgroundDarkGrey
]
_ ->
[ colourTheme.backgroundDarkGrey
, colourTheme.backgroundLightGrey
, colourTheme.backgroundLightGrey
]
}
, F.color colourTheme.textLightOrange
]
)
, paddingEach
{ top = 0
, right = 0
, bottom = 0
, left = 23
}
, spacing 12
, transitionStyleMedium
, width fill
]
++ (if route.isCurrent then
[ B.gradient
{ angle = 1.57
, steps =
case input.sharedModel.device.class of
Phone ->
[ colourTheme.backgroundDeepDarkGrey
, colourTheme.backgroundDeepDarkGrey
, colourTheme.backgroundDarkGrey
]
Tablet ->
[ colourTheme.backgroundDeepDarkGrey
, colourTheme.backgroundDeepDarkGrey
, colourTheme.backgroundDarkGrey
]
_ ->
[ colourTheme.backgroundDarkGrey
, colourTheme.backgroundDarkGrey
, colourTheme.backgroundDeepDarkGrey
]
}
, F.color colourTheme.textLightOrange
]
else
[]
)
++ (case input.sharedModel.device.class of
Phone ->
[ Events.onClick input.contentMessage ]
Tablet ->
[ Events.onClick input.contentMessage ]
_ ->
[]
)
)
[ itemIcon input route
2024-12-11 02:38:42 -06:00
, itemText input route
2024-12-23 03:15:35 -06:00
, case route.isNewTabLink of
True ->
itemLeavingIcon input route
False ->
none
2024-12-08 02:18:36 -06:00
]
2024-12-11 02:38:42 -06:00
, url = route.url
2024-12-08 02:18:36 -06:00
}
itemIcon : NavbarInput contentMsg -> RowInput contentMsg -> Element contentMsg
itemIcon input route =
2024-12-11 02:38:42 -06:00
el
([ height <| px 50
, width <| px 20
]
++ (if Maybe.Extra.isNothing route.sharedModel.user && route.isSubscriberOnly then
[ inFront <|
lock
{ elementAttributes =
[ moveDown 19
, moveLeft 20
, F.color colourTheme.barRed
]
, sharedModel = route.sharedModel
, svgAttributes = [ SvgAttr.width "12" ]
}
2024-12-08 02:18:36 -06:00
]
2024-12-11 02:38:42 -06:00
else
[]
)
)
<|
route.icon
{ elementAttributes =
[ centerX
, centerY
2024-12-08 02:18:36 -06:00
]
2024-12-11 02:38:42 -06:00
, sharedModel = route.sharedModel
, svgAttributes =
[ SvgAttr.width "30" ]
}
2024-12-08 02:18:36 -06:00
2024-12-23 03:15:35 -06:00
itemLeavingIcon : NavbarInput contentMsg -> RowInput contentMsg -> Element contentMsg
itemLeavingIcon input route =
el
[ height <| px 50
, width <| px 20
, E.alignRight
, paddingXY 10 0
]
<|
leaving
{ elementAttributes =
[ E.alignRight
, E.alignTop
, centerY
]
, sharedModel = route.sharedModel
, svgAttributes =
[ SvgAttr.width "15" ]
}
2024-12-11 02:38:42 -06:00
itemText : NavbarInput contentMsg -> RowInput contentMsg -> Element contentMsg
itemText input route =
el
[ specialNavbarTransition -- This special transition is needed to avoid weird animation sequencing rather in Chrome-based browsers.
, if input.model.isNavbarExpanded then
transparent False
else
transparent True
, F.bold
2024-12-23 03:15:35 -06:00
, paddingEach
{ top = 6
, right = 0
, bottom = 3
, left = 0
}
]
2024-12-11 02:38:42 -06:00
<|
text route.name
footerItems : NavbarInput contentMsg -> Element contentMsg
footerItems input =
row
([ scrollbarY
, height <| px 50
, transitionStyleMedium
, width <| px 223
]
++ (if input.model.isNavbarExpanded then
[]
else
[ transparent True ]
)
)
<|
List.map
(\x ->
makeFooterIcon input
{ icon = x.icon
, isNewTabLink = x.isNewTabLink
, url = x.url
, sharedModel = input.sharedModel
2024-12-08 03:04:37 -06:00
}
2024-12-11 02:38:42 -06:00
)
[ { icon = gitlab
, isNewTabLink = True
, url = "https://gitlab.com/upRootNutrition/website"
}
, { icon = twitter
, isNewTabLink = True
, url = "https://x.com/upRootNutrition"
}
2024-12-20 00:13:27 -06:00
-- , { icon = mastodon
-- , isNewTabLink = True
-- , url = "https://social.uprootnutrition.com/@nick"
-- }
2024-12-11 02:38:42 -06:00
, { icon = discord
, isNewTabLink = True
, url = "https://discord.gg/eeYQ2wJknS"
}
2024-12-08 03:04:37 -06:00
]
2024-12-11 02:38:42 -06:00
footerIcon : FooterInput contentMsg -> Element contentMsg
footerIcon route =
el
[ height <| px 50
, width <| px 20
, alignBottom
]
2024-12-11 02:38:42 -06:00
<|
route.icon
{ elementAttributes =
2024-12-08 03:04:37 -06:00
[ centerX
, centerY
2024-12-08 02:18:36 -06:00
]
2024-12-11 02:38:42 -06:00
, sharedModel = route.sharedModel
, svgAttributes =
[ SvgAttr.width "20" ]
}
2024-12-08 02:18:36 -06:00
2024-12-11 02:38:42 -06:00
makeFooterIcon : NavbarInput contentMsg -> FooterInput contentMsg -> Element contentMsg
makeFooterIcon input route =
row [ centerX ]
[ (if route.isNewTabLink then
newTabLink
else
link
)
[ width fill ]
{ label =
2024-12-08 21:16:04 -06:00
row
2024-12-11 02:38:42 -06:00
[ mouseOver
[ F.color colourTheme.textLightOrange
]
, paddingEach
{ top = 0
, right = 10
, bottom = 0
, left = 10
}
, transitionStyleMedium
, width fill
, F.color colourTheme.textLightGrey
]
[ footerIcon route
2024-12-08 21:16:04 -06:00
]
2024-12-11 02:38:42 -06:00
, url = route.url
2024-12-08 21:16:04 -06:00
}
]
2024-12-07 15:43:26 -06:00
2024-12-11 02:38:42 -06:00
-- Types:
2024-12-07 15:43:26 -06:00
2024-12-11 02:38:42 -06:00
type alias NavbarInput contentMsg =
{ route : Route ()
, sharedModel : Shared.Model
, model : Model
, contentMessage : contentMsg
, languageSelectorMessage : contentMsg
, content : View.View contentMsg
2024-12-08 02:18:36 -06:00
}
2024-12-11 02:38:42 -06:00
type alias NavbarMaker contentMsg =
NavbarInput contentMsg -> Element contentMsg
2024-12-07 15:43:26 -06:00
2024-12-11 02:38:42 -06:00
type alias NavbarLogoMaker contentMsg =
NavbarMaker contentMsg
2024-12-08 02:18:36 -06:00
2024-12-11 02:38:42 -06:00
type alias RowInput msg =
{ icon : TySvg.OuterPart msg -> Element msg
, isCurrent : Bool
, isNewTabLink : Bool
, isSubscriberOnly : Bool
, name : String
, url : String
, sharedModel : Shared.Model
2024-12-08 02:18:36 -06:00
}
2024-12-08 21:16:04 -06:00
2024-12-11 02:38:42 -06:00
type alias FooterInput msg =
{ icon : TySvg.OuterPart msg -> Element msg
, isNewTabLink : Bool
, url : String
, sharedModel : Shared.Model
}