How do I change the color of a link in Elm? - elm

I create links for a website in Elm with Text.link "https://somewebsite.com" (toText "SomeWebsite"). I would like to be able to set the color of the resultant text.
I have tried Text.link "https://somewebsite.com" (Text.color white <|toText "SomeWebsite") and Text.color white <|Text.link "https://somewebsite.com" (toText "SomeWebsite"), neither of which work, despite that the type signature of link is link : String -> Text -> Text. Both of these snippets compile.
I've looked through the source of elm-lang.org, which has links that look like they've been styled (they seem to have a different color than the default dark blue and no underlines) and haven't found anything that explains how it's done there.
How can I color the text of links in Elm?

The following will create a link to google that is red:
import Text (..)
main = toText "Google"
|> style {defaultStyle | color <- red, height <- Just 20 }
|> link "http://google.com"
|> leftAligned
Live demo here.
Unfortunately, this does not give you the power to really "style" the link when you hover over it which is a bit of a bummer.
The elm-lang website has the following styles at the top of its pages:
<style type="text/css">
a:link {text-decoration: none; color: rgb(15,102,230);}
a:visited {text-decoration: none}
a:active {text-decoration: none}
a:hover {text-decoration: underline; color: rgb(234,21,122);}
body { font-family: "Lucida Grande","Trebuchet MS","Bitstream Vera Sans",Verdana,Helvetica,sans-serif !important; }
p, li { font-size: 14px !important;
line-height: 1.5em !important; }
</style>
This gives its links the styling you see there.
However, it is still possible to get this type of styling using customButton from Graphics.Input.
import Graphics.Input as Input
click = Input.input ()
linkFormat = { defaultStyle | color <- blue }
hoverFormat = { linkFormat | bold <- True }
customLink url text =
let text' = Text.toText text
regular = Text.style linkFormat text' |> leftAligned
hover = Text.style hoverFormat text' |> leftAligned
down = Text.style linkFormat text' |> leftAligned
in link url <| Input.customButton click.handle () regular hover down
main = customLink "http://google.com" "Google"
Live demo here.
One thing to notice here is that I am not using Text.link. I am just using the link function from Graphics.Element which is imported by default and has the type String -> Element -> Element.
I hope this helps!

This no longer works on Elm 0.13, btw. It first says link is ambiguous between the one in the Graphics lib and the Text.link, so I qualify it by prepending Text. to link and then it complains that it 'Could not find variable 'Text.link'.' Same thing happens when I qualify it as a Graphics.Element.link.
it seems weird that I would not be able to qualify something by adding the module qualifier to it in Elm 0.13.
To accomplish this in 0.13, I figured out you can do the below.
import Text
main = link "http://www.google.com" <| leftAligned <| Text.color red <| toText "Google"
http://share-elm.com/sprout/5430943ee4b017b21db2f86c

Demo in Elm-0.18
module Main exposing (main)
import Html as H exposing (Html)
import Html.Attributes as HA
main : Html msg
main =
H.a
[ HA.href "https://en.wikipedia.org"
, HA.style [ ( "color", "green" ) ]
]
[ H.text "wikipedia" ]

Related

how to change the vue-intro.js css in nuxt.js

I'm trying to change the CSS feature vue-intro tutorial for my web app. I'm having trouble with how to change the tooltip button color, themes in vue-intro.js.
I want to change Next button color. so, how to change CSS in nuxt.js project.
I added the below code as a plugin. but I can't change the CSS
import Vue from 'vue'
import VueIntro from 'vue-introjs'
import 'intro.js/introjs.css'
Vue.use(VueIntro)
Here's an SCSS utility to generate the CSS for it:
$btn-color: #f50;
$text-color: white;
a.introjs-nextbutton {
background-color: $btn-color;
border-color: darken($btn-color, 4.2%);
text-shadow: none;
color: $text-color;
&:hover {
background-color: lighten($btn-color, 4.2%);
border-color: $btn-color;
color: $text-color;
}
&:focus {
box-shadow: 0 0 0 0.2rem transparentize($btn-color, .42);
background-color: $btn-color;
border-color: darken($btn-color, 4.2%);
color: $text-color;
}
}
I have done something similar before. I think the only way to do it is to overwrite the className or not import the intro.css (make your own). You need to "inspect element" to find out the introJS className from the library. Basically their className start with prefix introjs-something.
I can even do things like display none for previous button or change its color. See picture below.
Click this to see My Inspect Element to find introjs classes

Hide a component when clicked outside

What would be the right way to handle a click outside of a single component that is supposed to hide this component?
Example of such component might be a dropdown menu, a datepicker and the like. We typically expect them to hide when we click outside. But to do so, it seems like we have to perform some "impure" hacks that I'm not sure how to avoid in FRP style.
I searched for relevant React examples for ideas and found this but they all seem to rely on attaching callbacks to global objects that then modify internal component's state.
The existing answer doesn't work in elm v0.18 (Signal was removed in 0.17), so I wanted to update it. The idea is to add a top-level transparent backdrop behind the dropdown menu. This has the bonus effect of being able to darken everything behind the menu if you want.
This example model has a list of words, and any word may have a open dropdown (and some associated info), so I map across them to see if any of them are open, in which case I display the backdrop div in front of everything else:
There's a backdrop in the main view function:
view : Model -> Html Msg
view model =
div [] <|
[ viewWords model
] ++ backdropForDropdowns model
backdropForDropdowns : Model -> List (Html Msg)
backdropForDropdowns model =
let
dropdownIsOpen model_ =
List.any (isJust << .menuMaybe) model.words
isJust m =
case m of
Just _ -> True
Nothing -> False
in
if dropdownIsOpen model then
[div [class "backdrop", onClick CloseDropdowns] []]
else
[]
CloseDropdowns is handled in the app's top-level update function:
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
CloseDropdowns ->
let
newWords = List.map (\word -> { word | menuMaybe = Nothing } ) model.words
in
({model | words = newWords}, Cmd.none)
And styled things using scss:
.popup {
z-index: 100;
position: absolute;
box-shadow: 0px 2px 3px 2px rgba(0, 0, 0, .2);
}
.backdrop {
z-index: 50;
position: absolute;
background-color: rgba(0, 0, 0, .4);
top: 0;
right: 0;
bottom: 0;
left: 0;
}
The following example that does something similar to what you describe.
modal is presented with an address (to send a 'dismiss' event to), the current window dimensions, and an elm-html Html component (which is the thing to be focussed, like a datepicker or a form).
We attach a click handler to the surrounding element; having given it an appropriate id we can work out if received clicks apply to it or the child, and forward them on appropriately. The only really clever bit is the deployment of customDecoder to filter out clicks on the child element.
Elsewhere, on reception of the 'dismiss' event, our model state changes such that we no longer need to call modal.
This is quite a large code sample that makes use of a fair few elm packages, so please ask if anything requires further explanation
import Styles exposing (..)
import Html exposing (Attribute, Html, button, div, text)
import Html.Attributes as Attr exposing (style)
import Html.Events exposing (on, onWithOptions, Options)
import Json.Decode as J exposing (Decoder, (:=))
import Result
import Signal exposing (Message)
modal : (Signal.Address ()) -> (Int, Int) -> Html -> Html
modal addr size content =
let modalId = "modal"
cancel = targetWithId (\_ -> Signal.message addr ()) "click" modalId
flexCss = [ ("display", "flex")
, ("align-items", "center")
, ("justify-content", "center")
, ("text-align", "center")
]
in div (
cancel :: (Attr.id modalId) :: [style (flexCss ++ absolute ++ dimensions size)]
) [content]
targetId : Decoder String
targetId = ("target" := ("id" := J.string))
isTargetId : String -> Decoder Bool
isTargetId id = J.customDecoder targetId (\eyed -> if eyed == id then Result.Ok True else Result.Err "nope!")
targetWithId : (Bool -> Message) -> String -> String -> Attribute
targetWithId msg event id = onWithOptions event stopEverything (isTargetId id) msg
stopEverything = (Options True True)
A bit late to the party here, but I was struggling with exactly the same problem and the elm community on slack suggested a nice way of detecting click outside an element (let's say, a dropdown).
The idea is that you can attach a global listener to mousedown via BrowserEvents.onMouseDown and pass it a custom decoder that would decode target DOM node from the event object. By "decoding DOM node" I mean decoding only the id and parentNode properties of the node. parentNode will allow recursively travers the DOM tree and for each node check whether its id is the same as the id of the dropdown.
The code for this (in elm 0.19) looks like this:
-- the result answers the question: is the node outside of the dropdown?
isOutsideDropdown : String -> Decode.Decoder Bool
isOutsideDropdown dropdownId =
Decode.oneOf
[ Decode.field "id" Decode.string
|> Decode.andThen
(\id ->
if dropdownId == id then
-- found match by id
Decode.succeed False
else
-- try next decoder
Decode.fail "continue"
)
, Decode.lazy
(\_ -> isOutsideDropdown dropdownId |> Decode.field "parentNode")
-- fallback if all previous decoders failed
, Decode.succeed True
]
-- sends message Close if target is outside the dropdown
outsideTarget : String -> Decode.Decoder Msg
outsideTarget dropdownId =
Decode.field "target" (isOutsideDropdown "dropdown")
|> Decode.andThen
(\isOutside ->
if isOutside then
Decode.succeed Close
else
Decode.fail "inside dropdown"
)
-- subscribes to the global mousedown
subscriptions : Model -> Sub Msg
subscriptions _ =
Browser.Events.onMouseDown (outsideTarget "dropdown")
The code uses Json-Decode package that needs to be installed via elm install elm/json.
I also wrote an article explaining in details how this works, and have an example of a dropdown on github.

Text-shadow and background-clip css in Mozilla

I'm having an issue with the cross-browser compatibility of a css inset text-shadow effect. Specifically, I'm having an issue with Mozilla. Here is the code:
I have a container with various inner elements:
<div id='abstract'>
<span>Abstract</span>
</div>
Applied to it are the following styling rules:
#abstract span {
font-family : 'FuturaLT Heavy';
font-size : 21px;
line-height : 24px;
text-transform : uppercase;
color : transparent;
background-color : #565656;
text-shadow : 0px 2px 3px rgba(255, 255, 255, 0.5);
-webkit-background-clip : text;
-moz-background-clip : text;
background-clip : text;
}
The span appears as I want it to in Safari and Chrome:
http://harrysolovay.com/non_site_related/images/stackoverflow/1.png
Unfortunately, this is what gets displayed in Mozilla:
http://harrysolovay.com/non_site_related/images/stackoverflow/2.png
I used modernizr to test both text-shadow and background-clip: both properties exist and are functional in Mozilla, which is keeping me from writing javascript that only inserts the styles if the property exists. In other words, I've ruled this out as a solution.
How else can I fix this issue? Are there any other detection and fallback methods I should try? Is there a simple css solution (please say yes)? Any help, suggestions or comments would be greatly appreciated. Thank you.
I found a solution to my question.
First, add the following test to Modernizr:
`Modernizr.addTest('backgroundcliptext', function() {
var div = document.createElement('div');
div.style.webkitBackgroundClip = "text";
var text = div.style.cssText.indexOf('text');
if (text > 0) return true;
'Webkit Moz O ms Khtml'.replace(/([A-Za-z]*)/g,function(val){
if (val+'BackgroundClip' in div.style) return true;
});
});`
This tests not only that the background-clip property exists in the browser, but also that the text value exists as an understood value. Then, the boolean Modernizr.backgroundcliptext is true if browser is compatible. I wrote something like this:
if(Modernizr.backgroundcliptext) {
$('#abstract > span').css({
'color' : 'transparent',
'background-color' : '#565656',
'text-shadow' : '0px 2px 3px rgba(255, 255, 255, 0.5)',
'-webkit-background-clip' : 'text',
'-moz-background-clip' : 'text',
'background-clip' : 'text'
});
}
(with the text css set to have a black color, no background-color and no background-clip or text-shadow)
Although I came up with an indirect solution to this problem, I hope there will soon be a way to patch browsers without the background-clip : text value understanding. Please comment if you have any news at all on this front. Thank you.

add custom snippets to emmet

I'm using emmet with Brackets.
In this file lib/AppSupport/Brackets/extensions/user/brackets-emmet/snippets.json
I add this line at the right place :
"clearfix":".clearfix:before, .clearfix:after { content: \" \"; display: table; } .clearfix:after { clear: both; } /* For IE 6/7 only */ .clearfix { *zoom: 1; }",
This works but this not looks like a good practice so I try to create an other file mysnippets.json in the same folder with this tiny sample :
{
"css": {
"snippets": {
"test": "ok"
}
}
}
But it doesn't work (after save/relaunch).
Is it possible to add an external json in the same folder ? What's worng ?
Here is the solution for Brackets (testing on 43) :
http://circlewaves.com/blog/how-to-add-custom-snippets-to-emmet-for-brackets/
All you need — is to create a JSON-file called with name started with “snippets”, for example: snippets-mysnippets.json, snippets_team.json, snippets-php.json and etc; and set extension folder with this JSON file in Emmet options:
On my mac I add something like : /Users/benoit/Documents/Brackets/
adding snippets-css.json with this :
{
"css": {
"snippets": {
"reset":"/* http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 License: none (public domain) */\n html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } \n/* HTML5 display-role reset for older browsers */\n article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; } body { line-height: 1; } ol, ul { list-style: none; } blockquote, q { quotes: none; } blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; } table { border-collapse: collapse; border-spacing: 0; }",
"clearfix":".clearfix:before, .clearfix:after { content: \" \"; display: table; } .clearfix:after { clear: both; } /* For IE 6/7 only */ .clearfix { *zoom: 1; }" }
}
}
open brackets-emmet/main.js
define a variable at the near top like this:
var userSnippets = require('text!emmet/userSnippets.json');
and then find this line:
emmet.loadSystemSnippets(snippets);
copy it and replaces by this:
emmet.loadSystemSnippets(userSnippets);
and now, create a file named userSnippets.json in: brackets-emmet/node_modules/emmet/lib/
edit your custom snippets in here, finally is press F5 ( command + r ) to refresh Brackets.
Done! :)
The documentation at http://docs.emmet.io/customization/snippets/ directs you to create an extensions folder and place within it a snippets.json or snippets-*.json (where * can be any name). In the new json file, you create your new snippets or override the standard snippets in the standard snippets.json file. In the Emmet preferences, put the path to the extensions folder. In Win 7, it appears that you need forward slashes in the path name. Your custom snippets.json file will not be overridden with updates. Following this procedure works with Brackets sprint 41 on Win 7.
On my Windows I added to Brackets - emmet - preferences path:
C:/Users/Andrew/AppData/Roaming/Brackets/extensions/user
And created my own snippets.json in this folder and it works!
It looks like the Emmet extension for Brackets only loads snippets from that one location. So if you want to customize your snippets, it seems the only option is to edit that file (and re-apply your edits any time you update the extension version). The snippets.json format is officially documented here: http://docs.emmet.io/customization/snippets/
It would be nice if Emmet supported a separate user-editable config file, though. Might be worth filing an issue on the Emmet extension to request this...
"!!": "{<!DOCTYPE html>}>html[lang='dk']>(head>meta[charset='${charset}']+meta[http-equiv='X-UA-Compatible'][content='IE=edge']+meta[name='viewport'][content='width=device-width,initial-scale=1.0']+link[href=/css/bootstrap.min.css]+link:css+title>{titel})+(body>div.container>div.row>div.col-12)",
This worked for me and might work for you use it at your own risk!
Adding custom docksnippet to Emmet:
1). Go to Help --> Show Extension Folder.
2). Browse to: C:\Users\daniel\AppData\Roaming\Brackets\extensions\user\brackets-emmet\node_modules\emmet\lib\snippets.json and manke a backup of the file before you edit it!
3). Search snippts.json for "html" with Ctrl + F and look for "abbreviations".
4). Add custom template with hook:
"!!": "{}>html[lang='dk']>(head>meta[charset='${charset}']+meta[http-equiv='X-UA-Compatible'][content='IE=edge']+meta[name='viewport'][content='width=device-width,initial-scale=1.0']+link[href=/css/bootstrap.min.css]+link:css+title>{titel})+(body>div.container>div.row>div.col-12)",
5). Save the original snippts.json file and reload with extensions (F5).

remove 'Processing' instead of hide

When we start sorting or other things datatables has option to show 'Process' message. All is fine , only when it hides 'Processing' there is still stay space where 'Processing' is placed. So html table jumping down when Processing showing then when data have been loaded Processing hidding but html table isn't jumping back up so there is stay visible place for it.
Question, how to make datatable to remove Processing tag instead of just hide. Thanks
EDIT. I add html code
<div id="search_table_processing" class="dataTables_processing" style="visibility: hidden;">Processing...<img alt="< <" src="/themes/third_party/linkedin_search/img/165.gif"></div>
Well drat, I just ran into this and had to dig into it myself.
In version 1.9.0 you can search for this snippet:
an[i].style.visibility = bShow ? "visible" : "hidden";
(Found after searching for visibility.)
In the minified version it's currently this (using the NuGet package):
c[d].style.visibility=b?"visible":"hidden";
The problem is we neglected to style .dataTables_processing, as per the sample CSS files. Here's what one of the samples has for styling:
.dataTables_processing {
position: absolute;
top: 0px;
left: 50%;
width: 250px;
margin-left: -125px;
border: 1px solid #ddd;
text-align: center;
color: #999;
font-size: 11px;
padding: 2px 0;
}
Once it's styled (or bProcessing is set to false), there shouldn't be an issue.
If you're comfortable changing the functionality of the plug-in (if you think you can remember to change it back), then you could switch it to use display instead of visibility.
In case you are using Internationalisation - "oLanguage" attribute in your datatables constructor
replace the old sProcessing value with this in your localization file in order to place a custom image while processing :
"sProcessing": "<img src='/themes/third_party/linkedin_search/img/165.gif'/>",
and here is how you link your datatables to a localization file (which can be downloaded from the datatables website Internationalisation of datatables)
.
.
.
"oLanguage": {
"sUrl": "../../jQuery/dataTables/media/MyLanguageFilesFolder/en_US.txt"
}
.
.
.
If you not using the Internationalisation of datatables you can always set the "sProcessing" value with the suggested above...
here an example :
$(document).ready(function() {
$('#example').dataTable( {
"oLanguage": {
"sProcessing": "<img src='/themes/third_party/linkedin_search/img/165.gif'>"
}
} );
} );
Changing
an[i].style.visibility = bShow ? "visible" : "hidden";
to
an[i].style.display = bShow ? "block" : "none";
didn't work for me. However, I accomplished it by changing the statement to
if (bShow == false) {
an[i].style.display = "none";
}
else {
an[i].style.display = "block";
}
Hope this helps anyone who doesn't want to add any css code and just go right to the source!
For the Datatables version 1.9.4, just edit the file jquery.dataTables.js line 3005, and change the following:
an[i].style.visibility = bShow ? "visible" : "hidden";"block" : "none";
to
an[i].style.display = bShow ?
Worked for me!
If you want the text to go away while the backdrop should be there, why not just add:
div.dataTables_processing{ color: transparent; }