diff --git a/frontend/elm-srcs.nix b/frontend/elm-srcs.nix index 30a6fc4b..a2e3ea07 100644 --- a/frontend/elm-srcs.nix +++ b/frontend/elm-srcs.nix @@ -1,27 +1,7 @@ { - "krisajenkins/remotedata" = { - sha256 = "0m5bk0qhsjv14vajqrkph386696pnhj5rn51kgma8lwyvvx9ihw1"; - version = "6.0.1"; - }; - - "elm/json" = { - sha256 = "0kjwrz195z84kwywaxhhlnpl3p251qlbm5iz6byd6jky2crmyqyh"; - version = "1.1.3"; - }; - - "truqu/elm-base64" = { - sha256 = "12w68b4idbs2vn0gm0lj354pm745jb7n0fj69408mpvh5r1z4m1b"; - version = "2.0.4"; - }; - - "elm/regex" = { - sha256 = "0lijsp50w7n1n57mjg6clpn9phly8vvs07h0qh2rqcs0f1jqvsa2"; - version = "1.0.0"; - }; - - "elm/html" = { - sha256 = "1n3gpzmpqqdsldys4ipgyl1zacn0kbpc3g4v3hdpiyfjlgh8bf3k"; + "NoRedInk/elm-json-decode-pipeline" = { + sha256 = "0y25xn0yx1q2xlg1yx1i0hg4xq1yxx6yfa99g272z8162si75hnl"; version = "1.0.0"; }; @@ -35,8 +15,8 @@ version = "1.0.4"; }; - "elm/url" = { - sha256 = "0av8x5syid40sgpl5vd7pry2rq0q4pga28b4yykn9gd9v12rs3l4"; + "elm/html" = { + sha256 = "1n3gpzmpqqdsldys4ipgyl1zacn0kbpc3g4v3hdpiyfjlgh8bf3k"; version = "1.0.0"; }; @@ -45,8 +25,18 @@ version = "2.0.0"; }; - "NoRedInk/elm-json-decode-pipeline" = { - sha256 = "0y25xn0yx1q2xlg1yx1i0hg4xq1yxx6yfa99g272z8162si75hnl"; + "elm/json" = { + sha256 = "0kjwrz195z84kwywaxhhlnpl3p251qlbm5iz6byd6jky2crmyqyh"; + version = "1.1.3"; + }; + + "elm/regex" = { + sha256 = "0lijsp50w7n1n57mjg6clpn9phly8vvs07h0qh2rqcs0f1jqvsa2"; + version = "1.0.0"; + }; + + "elm/url" = { + sha256 = "0av8x5syid40sgpl5vd7pry2rq0q4pga28b4yykn9gd9v12rs3l4"; version = "1.0.0"; }; @@ -55,6 +45,21 @@ version = "2.3.4"; }; + "krisajenkins/remotedata" = { + sha256 = "0m5bk0qhsjv14vajqrkph386696pnhj5rn51kgma8lwyvvx9ihw1"; + version = "6.0.1"; + }; + + "rtfeldman/elm-css" = { + sha256 = "1gwhgqwclc7clk1ns4qqzyn7b4wvcmccg9qavvb8m694qmwlkzjy"; + version = "18.0.0"; + }; + + "truqu/elm-base64" = { + sha256 = "12w68b4idbs2vn0gm0lj354pm745jb7n0fj69408mpvh5r1z4m1b"; + version = "2.0.4"; + }; + "elm/bytes" = { sha256 = "02ywbf52akvxclpxwj9n04jydajcbsbcbsnjs53yjc5lwck3abwj"; version = "1.0.8"; @@ -65,11 +70,6 @@ version = "1.0.5"; }; - "rtfeldman/elm-hex" = { - sha256 = "1y0aa16asvwdqmgbskh5iba6psp43lkcjjw9mgzj3gsrg33lp00d"; - version = "1.0.0"; - }; - "elm/parser" = { sha256 = "0a3cxrvbm7mwg9ykynhp7vjid58zsw03r63qxipxp3z09qks7512"; version = "1.1.0"; @@ -85,18 +85,28 @@ version = "1.0.2"; }; + "robinheghan/murmur3" = { + sha256 = "15asmgr2zqh7rkywrg5647rpdqkpzxk02v5qc6ndj60jza3gsmjk"; + version = "1.0.0"; + }; + + "rtfeldman/elm-hex" = { + sha256 = "1y0aa16asvwdqmgbskh5iba6psp43lkcjjw9mgzj3gsrg33lp00d"; + version = "1.0.0"; + }; + "elm-explorations/test" = { sha256 = "1fsd7bajm7qa93r5pn3mdafqh3blpzya601jbs9l238p0hmvh576"; version = "1.2.2"; }; - "elm/svg" = { - sha256 = "1cwcj73p61q45wqwgqvrvz3aypjyy3fw732xyxdyj6s256hwkn0k"; - version = "1.0.1"; - }; - "elm/random" = { sha256 = "138n2455wdjwa657w6sjq18wx2r0k60ibpc4frhbqr50sncxrfdl"; version = "1.0.0"; }; -} + + "elm/svg" = { + sha256 = "1cwcj73p61q45wqwgqvrvz3aypjyy3fw732xyxdyj6s256hwkn0k"; + version = "1.0.1"; + }; +} \ No newline at end of file diff --git a/frontend/elm.json b/frontend/elm.json index 4963cd00..2e3bdd99 100644 --- a/frontend/elm.json +++ b/frontend/elm.json @@ -16,6 +16,7 @@ "elm/url": "1.0.0", "hecrj/html-parser": "2.3.4", "krisajenkins/remotedata": "6.0.1", + "rtfeldman/elm-css": "18.0.0", "truqu/elm-base64": "2.0.4" }, "indirect": { @@ -24,6 +25,7 @@ "elm/parser": "1.1.0", "elm/time": "1.0.0", "elm/virtual-dom": "1.0.2", + "robinheghan/murmur3": "1.0.0", "rtfeldman/elm-hex": "1.0.0" } }, diff --git a/frontend/registry.dat b/frontend/registry.dat index 800d95db..8dbe77f2 100644 Binary files a/frontend/registry.dat and b/frontend/registry.dat differ diff --git a/frontend/src/Main.elm b/frontend/src/Main.elm index 7b74999e..95e821e3 100644 --- a/frontend/src/Main.elm +++ b/frontend/src/Main.elm @@ -2,22 +2,9 @@ module Main exposing (main) import Browser import Browser.Navigation -import Html - exposing - ( Html - , a - , div - , footer - , header - , img - , li - , small - , span - , sup - , text - , ul - ) -import Html.Attributes +import Html as ElmHtml +import Html.Styled exposing (Html, a, div, footer, header, img, li, small, span, sup, text, ul) +import Html.Styled.Attributes exposing ( alt , class @@ -38,6 +25,7 @@ import Search , decodeNixOSChannels , defaultFlakeId ) +import Style exposing (withStyled) import Url @@ -339,7 +327,7 @@ view : Model -> { title : String - , body : List (Html Msg) + , body : List (ElmHtml.Html Msg) } view model = let @@ -379,44 +367,43 @@ view model = in { title = title , body = - [ div [] - [ header [] - [ div [ class "navbar navbar-static-top" ] - [ div [ class "navbar-inner" ] - [ div [ class "container" ] - [ a [ class "brand", href "https://nixos.org" ] - [ img [ alt "NixOS logo", src "https://nixos.org/logo/nix-wiki.png", class "logo" ] [] - ] - , div [] - [ ul [ class "nav pull-left" ] - (viewNavigation model.route) - ] + [ header [] + [ div [ class "navbar navbar-static-top" ] + [ div [ class "navbar-inner" ] + [ div [ class "container" ] + [ a [ class "brand", href "https://nixos.org" ] + [ img [ alt "NixOS logo", src "https://nixos.org/logo/nix-wiki.png", class "logo" ] [] + ] + , div [] + [ ul [ class "nav pull-left" ] + (viewNavigation model.route) ] ] ] ] - , div [ class "container main" ] - [ div [ id "content" ] [ viewPage model ] - , footer - [ class "container text-center" ] - [ div [] - [ span [] [ text "Please help us improve the search by " ] - , a - [ href "https://github.com/NixOS/nixos-search/issues" - ] - [ text "reporting issues" ] - , span [] [ text "." ] - ] - , div [] - [ span [] [ text "❤️ " ] - , span [] [ text "Elasticsearch instance graciously provided by " ] - , a [ href "https://bonsai.io" ] [ text "Bonsai" ] - , span [] [ text ". Thank you! ❤️ " ] + ] + , div [ class "container main" ] + [ div [ id "content" ] [ viewPage model ] + , footer + [ class "container text-center" ] + [ div [] + [ span [] [ text "Please help us improve the search by " ] + , a + [ href "https://github.com/NixOS/nixos-search/issues" ] + [ text "reporting issues" ] + , span [] [ text "." ] + ] + , div [] + [ span [] [ text "❤️ " ] + , span [] [ text "Elasticsearch instance graciously provided by " ] + , a [ href "https://bonsai.io" ] [ text "Bonsai" ] + , span [] [ text ". Thank you! ❤️ " ] ] ] ] ] + |> withStyled } @@ -465,13 +452,13 @@ viewPage model = div [] [ text "Not Found" ] Packages packagesModel -> - Html.map (\m -> PackagesMsg m) <| Page.Packages.view model.nixosChannels packagesModel + Html.Styled.map (\m -> PackagesMsg m) <| Page.Packages.view model.nixosChannels packagesModel Options optionsModel -> - Html.map (\m -> OptionsMsg m) <| Page.Options.view model.nixosChannels optionsModel + Html.Styled.map (\m -> OptionsMsg m) <| Page.Options.view model.nixosChannels optionsModel Flakes flakesModel -> - Html.map (\m -> FlakesMsg m) <| Page.Flakes.view model.nixosChannels flakesModel + Html.Styled.map (\m -> FlakesMsg m) <| Page.Flakes.view model.nixosChannels flakesModel diff --git a/frontend/src/Page/Flakes.elm b/frontend/src/Page/Flakes.elm index 5f33e7a2..5b931630 100644 --- a/frontend/src/Page/Flakes.elm +++ b/frontend/src/Page/Flakes.elm @@ -8,7 +8,7 @@ module Page.Flakes exposing ) import Browser.Navigation -import Html +import Html.Styled exposing ( Html , a @@ -17,12 +17,12 @@ import Html , strong , text ) -import Html.Attributes +import Html.Styled.Attributes exposing ( class , href ) -import Html.Events exposing (onClick) +import Html.Styled.Events exposing (onClick) import Http exposing (Body) import Page.Options exposing (Msg(..)) import Page.Packages exposing (Msg(..)) @@ -197,10 +197,10 @@ view nixosChannels model = body = case model of OptionModel model_ -> - Html.map OptionsMsg <| mkBody "Options" model_ Page.Options.viewSuccess Page.Options.viewBuckets Page.Options.SearchMsg + Html.Styled.map OptionsMsg <| mkBody "Options" model_ Page.Options.viewSuccess Page.Options.viewBuckets Page.Options.SearchMsg PackagesModel model_ -> - Html.map PackagesMsg <| mkBody "Packages" model_ Page.Packages.viewSuccess Page.Packages.viewBuckets Page.Packages.SearchMsg + Html.Styled.map PackagesMsg <| mkBody "Packages" model_ Page.Packages.viewSuccess Page.Packages.viewBuckets Page.Packages.SearchMsg in body diff --git a/frontend/src/Page/Options.elm b/frontend/src/Page/Options.elm index 28a20aa2..3250fc36 100644 --- a/frontend/src/Page/Options.elm +++ b/frontend/src/Page/Options.elm @@ -15,7 +15,7 @@ module Page.Options exposing ) import Browser.Navigation -import Html +import Html.Styled exposing ( Html , a @@ -28,14 +28,8 @@ import Html , text , ul ) -import Html.Attributes - exposing - ( class - , classList - , href - , target - ) -import Html.Events +import Html.Styled.Attributes exposing (class, classList, css, href, target) +import Html.Styled.Events exposing ( onClick ) @@ -49,6 +43,7 @@ import Search , NixOSChannel , decodeResolvedFlake ) +import Style import Utils @@ -185,15 +180,15 @@ viewResultItem : viewResultItem nixosChannels channel _ show item = let asPre value = - pre [] [ text value ] + pre [ css [ Style.pre.base ] ] [ text value ] asPreCode value = - div [] [ pre [] [ code [ class "code-block" ] [ text value ] ] ] + pre [ css [ Style.pre.base, Style.pre.code ] ] [ text value ] showDetails = if Just item.source.name == show then Just <| - div [ Html.Attributes.map SearchMsg Search.trapClick ] <| + div [ Html.Styled.Attributes.map SearchMsg Search.trapClick ] <| [ div [] [ text "Name" ] , div [] [ asPreCode item.source.name ] ] diff --git a/frontend/src/Page/Packages.elm b/frontend/src/Page/Packages.elm index 6d9f6d6e..30b7f04b 100644 --- a/frontend/src/Page/Packages.elm +++ b/frontend/src/Page/Packages.elm @@ -13,7 +13,7 @@ module Page.Packages exposing ) import Browser.Navigation -import Html +import Html.Styled exposing ( Html , a @@ -29,15 +29,8 @@ import Html , text , ul ) -import Html.Attributes - exposing - ( class - , classList - , href - , id - , target - ) -import Html.Events exposing (onClick) +import Html.Styled.Attributes exposing (class, classList, css, href, id, target) +import Html.Styled.Events exposing (onClick) import Http exposing (Body) import Json.Decode import Json.Decode.Pipeline @@ -51,6 +44,7 @@ import Search , NixOSChannel , viewBucket ) +import Style import Utils @@ -629,7 +623,7 @@ viewResultItem nixosChannels channel showInstallDetails show item = , class "tab-pane" , id "package-details-nixpkgs" ] - [ pre [ class "code-block shell-command" ] + [ pre [ css [ Style.pre.code, Style.pre.shell ] ] [ text "nix-env -iA nixos." , strong [] [ text item.source.attr_name ] ] @@ -651,7 +645,7 @@ viewResultItem nixosChannels channel showInstallDetails show item = , class "tab-pane" , id "package-details-nixpkgs" ] - [ pre [ class "code-block shell-command" ] + [ pre [ css [ Style.pre.code, Style.pre.shell ] ] [ text "nix-env -iA nixpkgs." , strong [] [ text item.source.attr_name ] ] @@ -674,7 +668,7 @@ viewResultItem nixosChannels channel showInstallDetails show item = , class "tab-pane" , id "package-details-nixpkgs" ] - [ pre [ class "code-block" ] + [ pre [ css [ Style.pre.code ] ] [ text <| " environment.systemPackages = [\n pkgs." , strong [] [ text item.source.attr_name ] , text <| "\n ];" @@ -702,7 +696,7 @@ viewResultItem nixosChannels channel showInstallDetails show item = , ( "active", List.member showInstallDetails [ Search.Unset, Search.ViaNixShell, Search.FromFlake ] ) ] ] - [ pre [ class "code-block shell-command" ] + [ pre [ css [ Style.pre.code, Style.pre.shell ] ] [ text "nix-shell -p " , strong [] [ text item.source.attr_name ] ] @@ -717,7 +711,7 @@ viewResultItem nixosChannels channel showInstallDetails show item = , ( "active", True ) ] ] - [ pre [ class "code-block shell-command" ] + [ pre [ css [ Style.pre.code, Style.pre.shell ] ] [ text "nix build " , strong [] [ text url ] , text "#" @@ -739,7 +733,7 @@ viewResultItem nixosChannels channel showInstallDetails show item = SearchMsg (Search.ShowDetails item.source.attr_name) trapClick = - Html.Attributes.map SearchMsg Search.trapClick + Html.Styled.Attributes.map SearchMsg Search.trapClick isOpen = Just item.source.attr_name == show @@ -783,7 +777,7 @@ renderSource : Search.ResultItem ResultItemSource -> List NixOSChannel -> String - -> Html.Attribute Msg + -> Html.Styled.Attribute Msg -> (String -> String diff --git a/frontend/src/Route.elm b/frontend/src/Route.elm index dd40b29c..5bdf920c 100644 --- a/frontend/src/Route.elm +++ b/frontend/src/Route.elm @@ -10,8 +10,8 @@ module Route exposing , searchTypeToTitle ) -import Html -import Html.Attributes +import Html.Styled +import Html.Styled.Attributes import Route.SearchQuery exposing (SearchQuery) import Url import Url.Builder exposing (QueryParameter) @@ -156,9 +156,9 @@ parser url = -- PUBLIC HELPERS -href : Route -> Html.Attribute msg +href : Route -> Html.Styled.Attribute msg href targetRoute = - Html.Attributes.href (routeToString targetRoute) + Html.Styled.Attributes.href (routeToString targetRoute) fromUrl : Url.Url -> Maybe Route diff --git a/frontend/src/Search.elm b/frontend/src/Search.elm index 204b3d82..9057add2 100644 --- a/frontend/src/Search.elm +++ b/frontend/src/Search.elm @@ -34,7 +34,7 @@ module Search exposing import Base64 import Browser.Dom import Browser.Navigation -import Html +import Html.Styled exposing ( Html , a @@ -52,12 +52,13 @@ import Html , text , ul ) -import Html.Attributes +import Html.Styled.Attributes exposing ( attribute , autofocus , class , classList + , css , disabled , href , id @@ -65,7 +66,7 @@ import Html.Attributes , type_ , value ) -import Html.Events +import Html.Styled.Events exposing ( onClick , onInput @@ -84,6 +85,7 @@ import Route ) import Route.SearchQuery import Set +import Style exposing (loading) import Task @@ -358,9 +360,9 @@ ensureLoading nixosChannels model = model -elementId : String -> Html.Attribute msg +elementId : String -> Html.Styled.Attribute msg elementId str = - Html.Attributes.id <| "result-" ++ str + Html.Styled.Attributes.id <| "result-" ++ str @@ -751,19 +753,15 @@ viewFlakes : -> SearchType -> List (Html msg) viewFlakes outMsg _ selectedCategory = - [ li [] - [ ul [] + [ li [ css [ Style.bucket.container ] ] + [ ul [ css [ Style.bucket.list ] ] (List.map (\category -> - li [] + li [ css [ Style.bucket.listItem ] ] [ a [ href "#" , onClick <| outMsg (SubjectChange category) - , classList - [ ( "selected" - , category == selectedCategory - ) - ] + , css [ Style.bucket.item, Style.bucket.selected (category == selectedCategory) ] ] [ span [] [ text <| searchTypeToTitle category ] , closeButton @@ -803,10 +801,10 @@ viewResult nixosChannels outMsg toRoute categoryName model viewSuccess viewBucke div [] [] RemoteData.Loading -> - div [ class "loader-wrapper" ] - [ ul [ class "search-sidebar" ] searchBuckets - , div [ class "loader" ] [ text "Loading..." ] - , h2 [] [ text "Searching..." ] + div [ css [ Style.loading.wrapper ] ] + [ ul [ css [ Style.layout.sidebar ] ] searchBuckets + , div [ css [ Style.loading.loader ] ] [ text "Loading..." ] + , h2 [ css [ Style.loading.headline ] ] [ text "Searching..." ] ] RemoteData.Success result -> @@ -816,20 +814,20 @@ viewResult nixosChannels outMsg toRoute categoryName model viewSuccess viewBucke in if result.hits.total.value == 0 && List.length buckets == 0 then div [ class "search-results" ] - [ ul [ class "search-sidebar" ] searchBuckets + [ ul [ css [ Style.layout.sidebar ] ] searchBuckets , viewNoResults categoryName ] else if List.length buckets > 0 then div [ class "search-results" ] - [ ul [ class "search-sidebar" ] <| List.append searchBuckets buckets + [ ul [ css [ Style.layout.sidebar ] ] <| List.append searchBuckets buckets , div [] (viewResults nixosChannels model result viewSuccess toRoute outMsg categoryName) ] else div [ class "search-results" ] - [ ul [ class "search-sidebar" ] searchBuckets + [ ul [ css [ Style.layout.sidebar ] ] searchBuckets , div [] (viewResults nixosChannels model result viewSuccess toRoute outMsg categoryName) ] @@ -855,7 +853,7 @@ viewResult nixosChannels outMsg toRoute categoryName model viewSuccess viewBucke in div [] [ div [ class "alert alert-error" ] - [ ul [ class "search-sidebar" ] searchBuckets + [ ul [ css [ Style.layout.sidebar ] ] searchBuckets , h4 [] [ text errorTitle ] , text errorMessage ] @@ -869,7 +867,7 @@ viewNoResults categoryName = div [ class "search-no-results" ] [ h2 [] [ text <| "No " ++ categoryName ++ " found!" ] , text "You might want to " - , Html.a [ href "https://nixos.org/manual/nixpkgs/stable/#chap-quick-start" ] [ text "add a package" ] + , a [ href "https://nixos.org/manual/nixpkgs/stable/#chap-quick-start" ] [ text "add a package" ] , text " or " , a [ href "https://github.com/NixOS/nixpkgs/issues/new?assignees=&labels=0.kind%3A+packaging+request&template=packaging_request.md&title=Package+request%3A+PACKAGENAME" ] [ text "make a packaging request" ] , text "." @@ -895,20 +893,19 @@ viewBucket title buckets searchMsgFor selectedBucket sets = [] else - [ li [] - [ ul [] + [ li [ css [ Style.bucket.container ] ] + [ ul [ css [ Style.bucket.list ] ] (List.append - [ li [ class "header" ] [ text title ] ] + [ li [ css [ Style.bucket.header ] ] [ text title ] ] (List.map (\bucket -> - li [] + li [ css [ Style.bucket.listItem ] ] [ a [ href "#" , onClick <| searchMsgFor bucket.key - , classList - [ ( "selected" - , List.member bucket.key selectedBucket - ) + , css + [ Style.bucket.item + , Style.bucket.selected (List.member bucket.key selectedBucket) ] ] [ span [] [ text bucket.key ] @@ -1041,7 +1038,7 @@ viewResults nixosChannels model result viewSuccess _ outMsg categoryName = String.fromInt result.hits.total.value in [ div [] - [ Html.map outMsg <| viewSortSelection model + [ Html.Styled.map outMsg <| viewSortSelection model , h2 [] (List.append [ text "Showing results " @@ -1067,7 +1064,7 @@ viewResults nixosChannels model result viewSuccess _ outMsg categoryName = ) ] , viewSuccess nixosChannels model.channel model.showInstallDetails model.show result.hits.hits - , Html.map outMsg <| viewPager model result.hits.total.value + , Html.Styled.map outMsg <| viewPager model result.hits.total.value ] @@ -1465,9 +1462,9 @@ showMoreButton toggle isOpen = -- Html Event Helpers -onClickStop : msg -> Html.Attribute msg +onClickStop : msg -> Html.Styled.Attribute msg onClickStop message = - Html.Events.custom "click" <| + Html.Styled.Events.custom "click" <| Json.Decode.succeed { message = message , stopPropagation = True @@ -1475,7 +1472,7 @@ onClickStop message = } -trapClick : Html.Attribute (Msg a b) +trapClick : Html.Styled.Attribute (Msg a b) trapClick = - Html.Events.stopPropagationOn "click" <| + Html.Styled.Events.stopPropagationOn "click" <| Json.Decode.succeed ( NoOp, True ) diff --git a/frontend/src/Style.elm b/frontend/src/Style.elm new file mode 100644 index 00000000..52698626 --- /dev/null +++ b/frontend/src/Style.elm @@ -0,0 +1,196 @@ +module Style exposing (bucket, layout, loading, pre, withStyled) + +import Css +import Css.Animations +import Css.Global +import Html as ElmHtml +import Html.Styled exposing (Html, div, toUnstyled) +import Html.Styled.Attributes exposing (css) + + +withStyled : List (Html msg) -> List (ElmHtml.Html msg) +withStyled children = + div [ css [ Css.position Css.relative, Css.minHeight <| Css.vh 100 ] ] + (Css.Global.global + [ Css.Global.body + [ Css.position Css.relative + , Css.minHeight <| Css.vh 100 + , Css.overflowY Css.auto + ] + , Css.Global.footer + [ Css.position Css.absolute + , Css.bottom Css.zero + , Css.width <| Css.pct 100 + , Css.height <| Css.rem 4 + ] + + --- Accessibility overrides, this should be changed once then entire app is using elm-css + , Css.Global.a [ Css.color <| Css.hex "007dbb" ] + , Css.Global.class "label-info" [ Css.backgroundColor <| Css.hex "007dbb" ] + , Css.Global.class "badge" [ Css.backgroundColor <| Css.hex "757575" ] + , Css.Global.class "pager" + [ Css.displayFlex + , Css.justifyContent Css.spaceBetween + , Css.alignItems Css.center + , Css.maxWidth <| Css.em 20 + , Css.margin2 Css.zero Css.auto + , Css.padding2 (Css.px 20) Css.zero + ] + ] + :: children + ) + |> toUnstyled + |> List.singleton + + +{-| Loading CSS Record +wrapper property to be used as wrapper of both loader and headline +-} +loading : { wrapper : Css.Style, loader : Css.Style, headline : Css.Style } +loading = + { wrapper = + Css.batch + [ Css.height <| Css.px 200 + , Css.overflow Css.hidden + , Css.position Css.relative + ] + , loader = + let + frameSolid = + [ Css.Animations.property "box-shadow" "0 0", Css.Animations.property "height" "4em" ] + + frameFade = + [ Css.Animations.property "box-shadow" "0 -2em", Css.Animations.property "height" "5em" ] + + load = + Css.batch + [ Css.backgroundColor Css.transparent + , Css.width <| Css.em 1 + , Css.animationDuration <| Css.sec 1 + , Css.animationIterationCount Css.infinite + , Css.animationName + (Css.Animations.keyframes + [ ( 0, frameSolid ), ( 40, frameFade ), ( 80, frameSolid ), ( 100, frameSolid ) ] + ) + ] + in + Css.batch + [ load + , Css.color <| Css.hex "000000" + , Css.textIndent <| Css.em -9999 + , Css.margin2 (Css.px 88) Css.auto + , Css.position Css.relative + , Css.fontSize <| Css.px 11 + , Css.animationDelay <| Css.sec -0.16 + , Css.before + [ load + , Css.position Css.absolute + , Css.property "content" "''" + , Css.left <| Css.em -1.5 + , Css.animationDelay <| Css.sec -0.32 + ] + , Css.after + [ load + , Css.position Css.absolute + , Css.property "content" "''" + , Css.left <| Css.em 1.5 + ] + ] + , headline = + Css.batch + [ Css.position Css.absolute + , Css.top <| Css.em 3 + , Css.width <| Css.pct 100 + , Css.textAlign Css.center + ] + } + + +{-| preformatted CSS Record +properties to be used to style pre and code tags +-} +pre : { base : Css.Style, code : Css.Style, shell : Css.Style } +pre = + { base = + Css.batch + [ Css.backgroundColor Css.transparent + , Css.margin Css.zero + , Css.padding Css.zero + , Css.border Css.zero + , Css.display Css.inline + ] + , code = + Css.batch + [ Css.backgroundColor <| Css.hex "333" + , Css.color <| Css.hex "fff" + , Css.padding <| Css.em 0.5 + , Css.margin Css.zero + , Css.display Css.block + , Css.cursor Css.text_ + ] + , shell = Css.before [ Css.property "content" "'$ '" ] + } + + +{-| bucket CSS Record +properties for side bar buckets +-} +bucket : { container : Css.Style, list : Css.Style, header : Css.Style, listItem : Css.Style, item : Css.Style, selected : Bool -> Css.Style } +bucket = + { container = + Css.batch + [ Css.marginBottom <| Css.em 1 + , Css.padding <| Css.em 1 + , Css.borderRadius <| Css.px 4 + , Css.border3 (Css.px 1) Css.solid (Css.hex "ccc") + ] + , list = Css.batch [ Css.listStyle Css.none, Css.margin Css.zero ] + , header = + Css.batch + [ Css.fontSize <| Css.em 1.2 + , Css.fontWeight Css.bold + , Css.marginBottom <| Css.em 0.5 + ] + , listItem = Css.marginBottom <| Css.em 0.2 + , item = + Css.batch + [ Css.displayFlex + , Css.justifyContent Css.spaceBetween + , Css.padding4 (Css.em 0.5) (Css.em 0.5) (Css.em 0.5) (Css.em 1) + , Css.color <| Css.hex "333" + , Css.textDecoration Css.none + , Css.hover + [ Css.textDecoration Css.none + , Css.backgroundColor <| Css.hex "eee" + , Css.color <| Css.hex "333" + , Css.borderRadius <| Css.px 4 + ] + ] + , selected = + \b -> + if b then + let + selected = + Css.batch + [ Css.backgroundColor <| Css.hex "0081c2" + , Css.color <| Css.hex "FFF" + , Css.textDecoration Css.none + ] + in + Css.batch + [ selected, Css.borderRadius <| Css.px 4, Css.hover [ selected ], Css.focus [ selected ] ] + + else + Css.batch [] + } + + +layout : { sidebar : Css.Style } +layout = + { sidebar = + Css.batch + [ Css.width <| Css.em 25 + , Css.listStyle Css.none + , Css.margin4 Css.zero (Css.em 1) Css.zero Css.zero + ] + } diff --git a/frontend/src/Utils.elm b/frontend/src/Utils.elm index b674db96..66c7e3ec 100644 --- a/frontend/src/Utils.elm +++ b/frontend/src/Utils.elm @@ -5,6 +5,7 @@ module Utils exposing import Html.Parser import Html.Parser.Util +import Html.Styled exposing (Html, fromUnstyled) toggleList : @@ -19,10 +20,11 @@ toggleList list item = List.append list [ item ] +showHtml : String -> Maybe (List (Html msg)) showHtml value = case Html.Parser.run <| String.trim value of Ok [ Html.Parser.Element "rendered-html" _ nodes ] -> - Just <| Html.Parser.Util.toVirtualDom nodes + Just <| (Html.Parser.Util.toVirtualDom nodes |> List.map fromUnstyled) _ -> Nothing diff --git a/frontend/src/index.scss b/frontend/src/index.scss index 9ce485c7..bea9c021 100644 --- a/frontend/src/index.scss +++ b/frontend/src/index.scss @@ -2,13 +2,6 @@ /* -- Utils ---------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ -@mixin terminal() { - background: #333; - color: #fff; - margin: 0; -} - - @mixin search-result-item() { .result-item-show-more-wrapper { text-align: center; @@ -47,37 +40,10 @@ /* -- Layout --------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ -body { - position: relative; - min-height: 100vh; - overflow-y: auto; - - & > div:first-child { - position: relative; - min-height: 100vh; - } -} - -.code-block { - display: block; - cursor: text; -} - -.shell-command:before { - content: "$ "; -} - #content { padding-bottom: 4rem; } -footer { - position: absolute; - bottom: 0; - width: 100%; - height: 4rem; -} - header .navbar.navbar-static-top { .brand { padding-bottom: 0; @@ -161,14 +127,6 @@ header .navbar.navbar-static-top { } } - // Loader during loading the search results - & > .loader-wrapper > h2 { - position: absolute; - top: 3em; - width: 100%; - text-align: center; - } - & > .search-no-results { padding: 2em 1em; text-align: center; @@ -199,79 +157,6 @@ header .navbar.navbar-static-top { } } - // Buckets - ul.search-sidebar { - width: 25em; - - list-style: none; - margin: 0 1em 0 0; - - & > li { - margin-bottom: 1em; - border: 1px solid #ccc; - padding: 1em; - border-radius: 4px; - - & > ul { - list-style: none; - margin: 0; - - & > li { - margin-bottom: 0.2em; - - &.header { - font-size: 1.2em; - font-weight: bold; - margin-bottom: 0.5em; - } - - & > a { - display: grid; - grid-template-columns: auto max-content; - color: #333; - padding: 0.5em 0.5em 0.5em 1em; - text-decoration: none; - - &:hover { - text-decoration: none; - background: #eee; - border-radius: 4px; - } - - & > span:first-child { - overflow: hidden; - } - & > span:last-child { - text-align: right; - margin-left: 0.3em; - } - - &.selected { - background: #0081c2; - color: #FFF; - border-radius: 4px; - position: relative; - & > span:last-child { - display: none; - - } - } - - & .close { - opacity: 1; - text-shadow: none; - color: inherit; - font-size: inherit; - padding-left: .5em; - padding-right: .5em; - } - } - } - } - } - } - - & > .search-results { display: flex; flex-direction: row; @@ -417,11 +302,6 @@ header .navbar.navbar-static-top { border: 1px solid #ddd; border-top: 0; } - - pre { - @include terminal; - } - } // programs @@ -457,24 +337,6 @@ header .navbar.navbar-static-top { font-weight: bold; text-align: right; } - - & > div:nth-child(2n) { - pre { - background: transparent; - margin: 0; - padding: 0; - border: 0; - vertical-align: inherit; - display: inline; - } - - pre code { - background: #333; - color: #fff; - padding: 0.5em - } - } - } } } @@ -493,84 +355,3 @@ header .navbar.navbar-static-top { } } } - -/* ------------------------------------------------------------------------- */ -/* -- Loader --------------------------------------------------------------- */ -/* ------------------------------------------------------------------------- */ - -.loader-wrapper { - height: 200px; - overflow: hidden; - position: relative; -} -.loader, -.loader:before, -.loader:after { - background: transparent; - -webkit-animation: load1 1s infinite ease-in-out; - animation: load1 1s infinite ease-in-out; - width: 1em; - height: 4em; -} -.loader { - color: #000000; - text-indent: -9999em; - margin: 88px auto; - position: relative; - font-size: 11px; - -webkit-transform: translateZ(0); - -ms-transform: translateZ(0); - transform: translateZ(0); - -webkit-animation-delay: -0.16s; - animation-delay: -0.16s; -} -.loader:before, -.loader:after { - position: absolute; - top: 0; - content: ''; -} -.loader:before { - left: -1.5em; - -webkit-animation-delay: -0.32s; - animation-delay: -0.32s; -} -.loader:after { - left: 1.5em; -} -@keyframes load1 { - 0%, - 80%, - 100% { - box-shadow: 0 0; - height: 4em; - } - 40% { - box-shadow: 0 -2em; - height: 5em; - } -} - -/* ------------------------------------------------------------------------- */ -/* -- Accessibility overrides ---------------------------------------------- */ -/* ------------------------------------------------------------------------- */ -.label-info { - background: #007dbb; -} - -a { - color: #007dbb; -} - -.pager { - display: flex; - justify-content: space-between; - align-items: center; - max-width: 20em; - margin: 0 auto; - padding: 20px 0; -} - -.badge { - background-color: #757575 -} \ No newline at end of file diff --git a/frontend/versions.dat b/frontend/versions.dat deleted file mode 100644 index b911b15b..00000000 Binary files a/frontend/versions.dat and /dev/null differ