-- | The `Bulma` module is a wrapper around the BULMA css framework. module Bulma where import Prelude import Data.Maybe (Maybe, fromMaybe) import Data.Tuple (Tuple, fst, snd) import Halogen.HTML as HH import DOM.HTML.Indexed as DHI import Halogen.HTML.Properties as HP import Halogen.HTML.Events as HE import MissingHTMLProperties as MissingProperties import CSSClasses as C import Halogen.HTML.Core (AttrName(..)) -- import Web.Event.Event (type_, Event, EventType(..)) -- import Web.UIEvent.MouseEvent (MouseEvent) -- package web-uievents checkbox :: forall w i. Array (HH.HTML w i) -> i -> HH.HTML w i checkbox content_ action = HH.label [ HP.classes C.label ] $ [ HH.input [ HE.onValueInput \ _ -> action, MissingProperties.ty "checkbox" ] ] <> content_ -- outside_link :: forall w i. Array HH.ClassName -> String -> String -> HH.HTML w i outside_link classes url title = HH.a [ HP.classes classes, HP.target "_blank", HP.href url ] [ HH.text title ] columns :: forall (w :: Type) (i :: Type). Array HH.ClassName -> Array (HH.HTML w i) -> HH.HTML w i columns classes = HH.div [ HP.classes (C.columns <> classes) ] columns_ :: forall (w :: Type) (i :: Type). Array (HH.HTML w i) -> HH.HTML w i columns_ = columns [] column :: forall (w :: Type) (i :: Type). Array HH.ClassName -> Array (HH.HTML w i) -> HH.HTML w i column classes = HH.div [ HP.classes (C.column <> classes) ] column_ :: forall (w :: Type) (i :: Type). Array (HH.HTML w i) -> HH.HTML w i column_ = column [] h1 :: forall (w :: Type) (a :: Type). String -> HH.HTML w a h1 title = HH.h1 [ HP.classes (C.title) ] [ HH.text title ] h3 :: forall (w :: Type) (a :: Type). String -> HH.HTML w a h3 title = HH.h3 [ HP.classes (C.title <> C.is5) ] [ HH.text title ] h4 :: forall (w :: Type) (a :: Type). String -> HH.HTML w a h4 title = HH.h4 [ HP.classes (C.title <> C.is5) ] [ HH.text title ] zone_rr_title :: forall (w :: Type) (a :: Type). String -> HH.HTML w a zone_rr_title title = HH.h3 [ HP.classes (C.title <> C.is5 <> C.has_text_light <> C.has_background_dark) ] [ HH.text title ] subtitle :: forall (w :: Type) (a :: Type). String -> HH.HTML w a subtitle title = HH.h2 [ HP.classes (C.subtitle <> C.is4) ] [ HH.text title ] hdiv :: forall (w :: Type) (a :: Type). Array (HH.HTML w a) -> HH.HTML w a hdiv = HH.div [ HP.classes [HH.ClassName "mt-5"] ] --offcolumn :: forall (w :: Type) (a :: Type). -- Int -> Int -> Array (HH.HTML w a) -> HH.HTML w a --offcolumn 0 size = HH.div [ HP.classes [HH.ClassName ("mt-"<>show size)] ] --offcolumn offset size -- = column [ HH.ClassName ("is-offset-" <> (show offset) <> " is-" <> (show size)) ] input_classes :: Array HH.ClassName input_classes = C.input <> C.is_small <> C.is_info table :: forall w i. HH.Node DHI.HTMLtable w i table prop xs = HH.table ([ HP.classes $ C.table ] <> prop) xs table_ :: forall w i. Array HH.ClassName -> HH.Node DHI.HTMLtable w i table_ classes prop xs = HH.table ([ HP.classes $ C.table <> classes] <> prop) xs table_header_owned_domains :: forall w i. HH.HTML w i table_header_owned_domains = HH.thead_ [ HH.tr_ [ HH.th_ [ HH.text "Name" ] , HH.th_ [ HH.text "" ] , HH.th_ [ HH.text "" ] , HH.th_ [ HH.text "" ] ] ] table_header_shared_domains :: forall w i. HH.HTML w i table_header_shared_domains = HH.thead_ [ HH.tr_ [ HH.th_ [ HH.text "Name" ] , HH.th_ [ HH.text "Share key" ] , HH.th_ [ HH.text "" ] , HH.th_ [ HH.text "" ] ] ] mechanism_table_header :: forall w i. HH.HTML w i mechanism_table_header = HH.thead_ [ HH.tr_ [ HH.th_ [ HH.text "Policy" ] , HH.th_ [ HH.text "Type" ] , HH.th_ [ HH.text "Value" ] , HH.th_ [ HH.text "" ] ] ] modifier_table_header :: forall w i. HH.HTML w i modifier_table_header = HH.thead_ [ HH.tr_ [ HH.th_ [ HH.text "Type" ] , HH.th_ [ HH.text "Value" ] , HH.th_ [ HH.text "" ] ] ] dmarc_dmarcuri_table_header :: forall w i. HH.HTML w i dmarc_dmarcuri_table_header = HH.thead_ [ HH.tr_ [ HH.th_ [ HH.text "Email address" ] , HH.th_ [ HH.text "Report size limit" ] , HH.th_ [ HH.text "" ] ] ] name_header :: forall w i. HH.HTML w i name_header = HH.abbr [ HP.title "Name of the DNS entry, the fully-qualified-domain-name is .." ] [ HH.text "Name" ] ttl_header :: forall w i. HH.HTML w i ttl_header = HH.abbr [ HP.title "Time-to-Live, nb seconds before being considered invalid" ] [ HH.text "TTL" ] target_header :: forall w i. HH.HTML w i target_header = HH.abbr [ HP.title "In the DNS jargon, the target means the most important value associated with the entry, for an A entry it would be an IPv4 address, for example" ] [ HH.text "Target" ] token_header :: forall w i. HH.HTML w i token_header = HH.abbr [ HP.title "Tokens are used to update the entry, see the tab: \"Tokens? 🤨\"" ] [ HH.text "Token" ] priority_header :: forall w i. HH.HTML w i priority_header = HH.abbr [ HP.title "A numeric value that indicates the preference of the server (lower values indicate higher priority)" ] [ HH.text "Priority" ] weight_header :: forall w i. HH.HTML w i weight_header = HH.abbr [ HP.title "A relative weight used when multiple servers have the same priority, determining how often they should be used" ] [ HH.text "Weight" ] srv_mechanisms_header :: forall w i. HH.HTML w i srv_mechanisms_header = HH.abbr [ HP.title "Mechanisms specify which mail servers are allowed to send mail for the domain and how to evaluate the sending mail server’s IP address" ] [ HH.text "Mechanisms" ] srv_modifiers_header :: forall w i. HH.HTML w i srv_modifiers_header = HH.abbr [ HP.title "Modifiers provide additional instructions, such as explanations for SPF failures or redirecting SPF checks to another domain" ] [ HH.text "Modifiers" ] srv_default_policy_header :: forall w i. HH.HTML w i srv_default_policy_header = HH.abbr [ HP.title "" ] [ HH.text "Default Policy" ] protocol_header :: forall w i. HH.HTML w i protocol_header = HH.abbr [ HP.title "The related communication protocol, either TCP or UDP (want more? Just ask me)" ] [ HH.text "Protocol" ] port_header :: forall w i. HH.HTML w i port_header = HH.abbr [ HP.title "Related connection port" ] [ HH.text "Port" ] dkim_notes_header :: forall w i. HH.HTML w i dkim_notes_header = HH.abbr [ HP.title "Arbitrary string related to this cryptographic material" ] [ HH.text "Notes" ] dmarc_policy_header :: forall w i. HH.HTML w i dmarc_policy_header = HH.abbr [ HP.title "How to handle email when SPF and DKIM aren't valid?" ] [ HH.text "Policy" ] dmarc_subdom_policy_header :: forall w i. HH.HTML w i dmarc_subdom_policy_header = HH.abbr [ HP.title "How to handle email when SPF and DKIM aren't valid?" ] [ HH.text "Subdomain Policy" ] dmarc_dkim_policy_header :: forall w i. HH.HTML w i dmarc_dkim_policy_header = HH.abbr [ HP.title "What should be considered acceptable to do with an email not conforming with DKIM" ] [ HH.text "DKIM Policy" ] dmarc_spf_policy_header :: forall w i. HH.HTML w i dmarc_spf_policy_header = HH.abbr [ HP.title "What should be considered acceptable to do with an email not conforming with SPF" ] [ HH.text "SPF Policy" ] dmarc_sample_rate_header :: forall w i. HH.HTML w i dmarc_sample_rate_header = HH.abbr [ HP.title "Percentage of messages subjected to the requested policy [0-100]" ] [ HH.text "Sample Rate" ] dmarc_report_on_header :: forall w i. HH.HTML w i dmarc_report_on_header = HH.abbr [ HP.title "What error should be reported? DKIM, SPF, Both, Any or None?" ] [ HH.text "Report on" ] dmarc_report_interval_header :: forall w i. HH.HTML w i dmarc_report_interval_header = HH.abbr [ HP.title "Minimal duration between two DMARC reports (in seconds)" ] [ HH.text "Report interval" ] simple_table_header :: forall w i. HH.HTML w i simple_table_header = HH.thead_ [ HH.tr_ [ HH.th_ [ HH.text "Type" ] , HH.th_ [ name_header ] , HH.th_ [ ttl_header ] , HH.th_ [ target_header ] , HH.th_ [ HH.text "" ] , HH.th_ [ token_header ] ] ] simple_table_header_ro :: forall w i. HH.HTML w i simple_table_header_ro = HH.thead_ [ HH.tr [ HP.classes C.has_background_warning_light ] [ HH.th [ HP.style "width: 50px;" ] [ HH.text "Type" ] , HH.th_ [ name_header ] , HH.th_ [ ttl_header ] , HH.th_ [ target_header ] , HH.th_ [ HH.text "" ] ] ] mx_table_header :: forall w i. HH.HTML w i mx_table_header = HH.thead_ [ HH.tr_ [ HH.th_ [ name_header ] , HH.th_ [ ttl_header ] , HH.th_ [ priority_header ] , HH.th_ [ target_header ] , HH.th_ [ HH.text "" ] ] ] caa_table_header :: forall w i. HH.HTML w i caa_table_header = HH.thead_ [ HH.tr_ [ HH.th_ [ name_header ] , HH.th_ [ ttl_header ] , HH.th_ [ HH.text "Flag" ] , HH.th_ [ HH.text "Tag" ] , HH.th_ [ HH.text "Value" ] , HH.th_ [ HH.text "" ] ] ] srv_table_header :: forall w i. HH.HTML w i srv_table_header = HH.thead_ [ HH.tr_ [ HH.th_ [ name_header ] , HH.th_ [ protocol_header ] , HH.th_ [ target_header ] , HH.th_ [ port_header ] , HH.th_ [ ttl_header ] , HH.th_ [ priority_header ] , HH.th_ [ weight_header ] , HH.th_ [ HH.text "" ] ] ] spf_table_header :: forall w i. HH.HTML w i spf_table_header = HH.thead_ [ HH.tr_ [ HH.th_ [ name_header ] , HH.th_ [ ttl_header ] -- , HH.th_ [ HH.text "Version" ] -- For now, version isn't displayed. , HH.th_ [ srv_mechanisms_header ] , HH.th_ [ srv_modifiers_header ] , HH.th_ [ srv_default_policy_header ] , HH.th_ [ HH.text "" ] ] ] dkim_table_header :: forall w i. HH.HTML w i dkim_table_header = HH.thead_ [ HH.tr_ [ HH.th_ [ name_header ] , HH.th_ [ ttl_header ] -- , HH.th_ [ HH.text "Version" ] -- For now, version isn't displayed. Assume DKIM1. , HH.th_ [ HH.text "Hash algo" ] , HH.th_ [ HH.text "Signature algo" ] , HH.th_ [ HH.text "Public Key" ] , HH.th_ [ dkim_notes_header ] , HH.th_ [ HH.text "" ] ] ] dmarc_table_header :: forall w i. HH.HTML w i dmarc_table_header = HH.thead_ [ HH.tr_ [ HH.th_ [ name_header ] , HH.th_ [ ttl_header ] -- , HH.th_ [ HH.text "Version" ] -- For now, version isn't displayed. Assume DMARC1. , HH.th_ [ dmarc_policy_header ] -- p , HH.th_ [ dmarc_subdom_policy_header ] -- sp , HH.th_ [ dmarc_dkim_policy_header ] -- adkim , HH.th_ [ dmarc_spf_policy_header ] -- aspf , HH.th_ [ dmarc_sample_rate_header ] -- pct , HH.th_ [ dmarc_report_on_header ] -- fo , HH.th_ [ dmarc_report_interval_header ] -- ri -- TODO? rua & ruf -- , HH.th_ [ HH.text "Accepted report formats" ] -- For now, assume AFRF. , HH.th_ [ HH.text "" ] ] ] name_soa_header :: forall w i. HH.HTML w i name_soa_header = HH.abbr [ HP.title "Your actual domain name (technical term: \"fully qualified domain name\")." ] [ HH.text "Name" ] mname_soa_header :: forall w i. HH.HTML w i mname_soa_header = HH.abbr [ HP.title "Domain name of the primary authoritative DNS server for the zone (SOA \"MNAME\" field)." ] [ HH.text "Primary NS" ] rname_soa_header :: forall w i. HH.HTML w i rname_soa_header = HH.abbr [ HP.title "The email address of the person responsible for managing the zone (the \"@\" is replaced by \".\" for some reason). This is the SOA \"RNAME\" field." ] [ HH.text "Contact" ] serial_soa_header :: forall w i. HH.HTML w i serial_soa_header = HH.abbr [ HP.title "A number that is incremented every time the zone is updated. Secondary DNS servers use this number to check for updates." ] [ HH.text "Serial" ] refresh_soa_header :: forall w i. HH.HTML w i refresh_soa_header = HH.abbr [ HP.title "The interval (in seconds) at which secondary DNS servers should check the primary server for changes to the zone." ] [ HH.text "Refresh" ] retry_soa_header :: forall w i. HH.HTML w i retry_soa_header = HH.abbr [ HP.title "The time in seconds that secondary servers should wait before retrying a failed attempt to contact the primary DNS server." ] [ HH.text "Retry" ] expire_soa_header :: forall w i. HH.HTML w i expire_soa_header = HH.abbr [ HP.title "The time in seconds that secondary DNS servers will keep the zone data before discarding it if they cannot contact the primary server." ] [ HH.text "Expire" ] minttl_soa_header :: forall w i. HH.HTML w i minttl_soa_header = HH.abbr [ HP.title "The minimum time (in seconds) that other DNS servers should cache negative responses (e.g., for non-existent domain names)." ] [ HH.text "Minimum TTL" ] soa_table_header :: forall w i. HH.HTML w i soa_table_header = HH.thead_ [ HH.tr [ HP.classes C.has_background_warning_light ] [ HH.th_ [ name_soa_header ] , HH.th_ [ ttl_header ] , HH.th_ [ mname_soa_header ] , HH.th_ [ rname_soa_header ] , HH.th_ [ serial_soa_header ] , HH.th_ [ refresh_soa_header ] , HH.th_ [ retry_soa_header ] , HH.th_ [ expire_soa_header ] , HH.th_ [ minttl_soa_header ] ] ] txt_name :: forall w i. String -> HH.HTML w i txt_name t = HH.td [ rr_name_style ] [ rr_name_text ] where rr_name_style = HP.style "width: 80px;" rr_name_text = HH.text t textarea_ :: forall w i. Array HH.ClassName -> String -> String -> (String -> i) -> HH.HTML w i textarea_ classes placeholder value action = HH.textarea [ HE.onValueInput action , HP.value value , HP.placeholder placeholder , HP.classes $ C.textarea <> classes ] textarea :: forall w i. String -> String -> (String -> i) -> HH.HTML w i textarea placeholder value action = textarea_ [] placeholder value action btn_abbr_ :: forall w action. Array HH.ClassName -- button classes -> Array HH.ClassName -- inner div classes -> String -> String -> action -> HH.HTML w action btn_abbr_ btnclasses divclasses explanation_ title action = HH.button [ HE.onClick \_ -> action , HP.classes $ C.button <> btnclasses ] [ HH.abbr [ HP.title explanation_ ] [ HH.div [ HP.classes divclasses ] [ HH.text title ] ] ] btn_abbr :: forall w action. String -> String -> action -> HH.HTML w action btn_abbr explanation_ title action = btn_abbr_ [] [] explanation_ title action alert_btn_abbr :: forall w action. String -> String -> action -> HH.HTML w action alert_btn_abbr explanation_ title action = btn_abbr_ C.is_danger [] explanation_ title action btn_modify :: forall w i. i -> HH.HTML w i btn_modify action = btn_abbr_ (C.is_small <> C.is_info) (C.is_size 4) "Edit" "⚒" action btn_save :: forall w i. i -> HH.HTML w i btn_save action = btn_ C.is_info "Save" action btn_add :: forall w i. i -> HH.HTML w i btn_add action = btn_ C.is_info "Add" action btn_delete :: forall w i. i -> HH.HTML w i btn_delete action = btn_abbr_ (C.is_small <> C.is_danger) (C.is_size 4) "Delete" "✖" action btn_modify_ro :: forall w i. HH.HTML w i btn_modify_ro = btn_ro (C.is_small <> C.is_warning) "modify" btn_readonly :: forall w i. HH.HTML w i btn_readonly = btn_ro (C.is_small <> C.is_warning) "read only" btn_delete_ro :: forall w i. HH.HTML w i btn_delete_ro = btn_ro (C.is_small <> C.is_warning) "remove" btn_ro :: forall w i. Array HH.ClassName -> String -> HH.HTML w i btn_ro classes title = HH.button [ HP.classes $ C.button <> classes ] [ HH.text title ] -- | Create a `level`, different components that should appear on the same horizontal line. -- | First argument, elements that should appear on the left, second on the right. level :: forall w i. Array (HH.HTML w i) -> Array (HH.HTML w i) -> HH.HTML w i level left right = HH.nav [ HP.classes C.level ] [ HH.div [ HP.classes C.level_left ] $ itemize left , HH.div [ HP.classes C.level_right ] $ itemize right ] where itemize = map (\v -> HH.div [ HP.classes C.level_item ] [v]) btn_ :: forall w action. Array HH.ClassName -> String -> action -> HH.HTML w action btn_ classes title action = HH.button [ HE.onClick \_ -> action , HP.classes $ C.button <> classes ] [ HH.text title ] btn :: forall w action. String -> action -> HH.HTML w action btn title action = btn_ [] title action alert_btn :: forall w action. String -> action -> HH.HTML w action alert_btn title action = btn_ C.is_danger title action render_input :: forall w i. Boolean -> String -> String -> (String -> i) -> String -> (HP.IProp DHI.HTMLinput i) -> HH.HTML w i render_input password id placeholder action value cond = HH.input $ [ HE.onValueInput action , HP.value value , HP.placeholder placeholder , HP.classes $ input_classes , HP.id id , cond ] <> case password of false -> [] true -> [ HP.type_ HP.InputPassword ] -- | Bulma's `field`, which contains an array of `Halogen.HTML` entries. -- | Two entries are expected: a field label (`div_field_label`) and a field content (`div_field_content`). div_field :: forall w i. Array HH.ClassName -> Array (HH.HTML w i) -> HH.HTML w i div_field classes = HH.div [HP.classes (C.field <> C.is_horizontal <> classes)] -- | Field label (id and title) for a Bulma `field`. div_field_label :: forall w i. String -> String -> HH.HTML w i div_field_label id title = HH.div [HP.classes (C.field_label <> C.normal)] [HH.label [ HP.classes C.label, HP.for id ] [ HH.text title ]] -- | Any `Halogen.HTML` data in Bulma `field-body > field > control` divs. div_field_content :: forall w i. HH.HTML w i -> HH.HTML w i div_field_content content = HH.div [ HP.classes C.field_body ] [ HH.div [HP.classes C.field ] [ HH.div [HP.classes C.control ] [ content ] ] ] -- | Basic field entry with a title and a field content. -- | -- |``` -- |div [field is-horizontal] -- | div [field-label is-normal] -- | label [for-id] -- | text -- | div [field-body] -- | div [field] -- | div [control] -- |``` field_entry :: forall w i. String -> String -> HH.HTML w i -> HH.HTML w i field_entry id title entry = div_field [] [ div_field_label id title , div_field_content entry ] -- | Error field entry with a title and a field content. error_field_entry :: forall w i. String -> String -> HH.HTML w i -> HH.HTML w i error_field_entry id title entry = div_field C.has_background_danger_light [ div_field_label id title , div_field_content entry ] error_box :: forall w i. String -> String -> String -> HH.HTML w i error_box id title value = error_field_entry id title $ notification_danger' value field_inner :: forall w i. Boolean -> (HP.IProp DHI.HTMLinput i) -> String -> String -> String -> (String -> i) -> String -> HH.HTML w i field_inner ispassword cond id title placeholder action value = field_entry id title $ render_input ispassword id placeholder action value cond div_field_ :: forall w i. Array HH.ClassName -> Array (HH.HTML w i) -> HH.HTML w i div_field_ classes = HH.div [ HP.classes (C.field <> classes) ] btn_labeled :: forall w i. String -> String -> String -> i -> HH.HTML w i btn_labeled id title button_text action = field_entry id title $ HH.button [ HE.onClick \_ -> action , HP.classes $ C.button <> C.is_small <> C.is_info , HP.id id ] [ HH.text button_text ] box_input_ :: forall w i. (HP.IProp DHI.HTMLinput i) -> String -> String -> String -> (String -> i) -> String -> HH.HTML w i box_input_ = field_inner false box_password_ :: forall w i. (HP.IProp DHI.HTMLinput i) -> String -> String -> String -> (String -> i) -> String -> HH.HTML w i box_password_ = field_inner true box_input :: forall w i. String -> String -> String -> (String -> i) -> String -> HH.HTML w i box_input = box_input_ (HP.enabled true) box_password :: forall w i. String -> String -> String -> (String -> i) -> String -> HH.HTML w i box_password = box_password_ (HP.enabled true) section_small :: forall w i. Array (HH.HTML w i) -> HH.HTML w i section_small = HH.section [ HP.classes (C.section <> C.is_small) ] section_medium :: forall w i. Array (HH.HTML w i) -> HH.HTML w i section_medium = HH.section [ HP.classes (C.section <> C.medium) ] new_domain_field :: forall w i. (String -> i) -> String -> Array (HP.IProp DHI.HTMLselect i) -> Array String -> HH.HTML w i new_domain_field inputaction text_ selectaction accepted_domains = div_field_ C.has_addons [ HH.p [ HP.classes C.control ] [ HH.input $ [ HE.onValueInput inputaction , HP.placeholder "www" , HP.value text_ , HP.type_ HP.InputText , HP.classes (C.is_primary <> C.input) ] ] , HH.p [ HP.classes C.control ] [ select selectaction $ map option accepted_domains ] ] code :: forall w i. String -> HH.HTML w i code str = HH.code_ [ HH.text str ] text :: forall w i. String -> HH.HTML w i text = HH.text p :: forall w i. String -> HH.HTML w i p str = HH.p_ [ HH.text str ] p_ :: forall w i. Array HH.ClassName -> String -> HH.HTML w i p_ classes str = HH.p [HP.classes classes] [ HH.text str ] box :: forall w i. Array (HH.HTML w i) -> HH.HTML w i box = HH.div [HP.classes C.box] box_ :: forall w i. Array HH.ClassName -> Array (HH.HTML w i) -> HH.HTML w i box_ classes = HH.div [HP.classes $ C.box <> classes] option :: forall w i. String -> HH.HTML w i option value = HH.option_ [HH.text value] select :: forall w i. HH.Node DHI.HTMLselect w i select action options = HH.div [ HP.classes (C.select <> C.is_primary) ] [ HH.select action options] hero :: forall w i. String -> String -> HH.HTML w i hero _title _subtitle = HH.section [ HP.classes (C.hero <> C.is_info <> C.is_small) ] [ HH.div [ HP.classes C.hero_body ] [ HH.p [ HP.classes C.title ] [ HH.text _title ] , HH.p [ HP.classes C.subtitle ] [ HH.text _subtitle ] ] ] small_hero :: forall w i. String -> String -> HH.HTML w i small_hero _title _subtitle = HH.section [ HP.classes (C.hero <> C.is_info <> C.is_small) ] [ HH.div [ HP.classes C.hero_body ] [ HH.div [ HP.classes $ C.container <> C.has_text_centered ] [ HH.p [ HP.classes C.title ] [ HH.text _title ] , HH.p [ HP.classes C.subtitle ] [ HH.text _subtitle ] ] ] ] hero_danger_txt :: forall w i. String -> String -> HH.HTML w i hero_danger_txt _title _subtitle = hero_danger [ HH.text _title ] [ HH.text _subtitle ] hero_danger :: forall w i. Array (HH.HTML w i) -> Array (HH.HTML w i) -> HH.HTML w i hero_danger _title _subtitle = HH.section [ HP.classes (C.hero <> C.is_danger <> C.is_small) ] [ HH.div [ HP.classes C.hero_body ] [ HH.p [ HP.classes C.title ] _title , HH.p [ HP.classes C.subtitle ] _subtitle ] ] header :: forall w i. String -> String -> HH.HTML w i header = hero container :: forall w i. Array (HH.HTML w i) -> HH.HTML w i container = HH.div [HP.classes (C.container <> C.is_info)] data_target :: forall r i. String -> HP.IProp r i data_target = HP.attr (AttrName "data-target") modal_ :: forall w i. Array (HH.HTML w i) -> HH.HTML w i modal_ = HH.div [HP.classes (C.modal <> C.is_active)] modal_background :: forall w i. HH.HTML w i modal_background = HH.div [HP.classes C.modal_background] [] modal_card_large :: forall w i. Array (HH.HTML w i) -> HH.HTML w i modal_card_large = HH.div [HP.classes $ C.modal_card <> C.is_large] modal_header :: forall w i. String -> HH.HTML w i modal_header title = HH.header [HP.classes C.modal_card_head] [ HH.p [HP.classes C.modal_card_title] [HH.text title] ] modal_body :: forall w i. Array (HH.HTML w i) -> HH.HTML w i modal_body = HH.section [HP.classes C.modal_card_body] modal_foot :: forall w i. Array (HH.HTML w i) -> HH.HTML w i modal_foot = HH.div [HP.classes C.modal_card_foot] cancel_button :: forall w i. i -> HH.HTML w i cancel_button action = HH.button [ HP.classes C.button , HE.onClick \_ -> action ] [HH.text "Cancel"] strong :: forall w i. String -> HH.HTML w i strong str = HH.strong_ [ HH.text str ] hr :: forall w i. HH.HTML w i hr = HH.hr_ tile :: forall w i. Array HH.ClassName -> Array (HH.HTML w i) -> HH.HTML w i tile classes = HH.div [HP.classes (C.tile <> classes)] tile_ :: forall w i. Array (HH.HTML w i) -> HH.HTML w i tile_ = tile [] tile_danger :: forall w i. Array HH.ClassName -> Array (HH.HTML w i) -> HH.HTML w i tile_danger classes = tile (C.is_danger <> C.notification <> classes) tile_warning :: forall w i. Array HH.ClassName -> Array (HH.HTML w i) -> HH.HTML w i tile_warning classes = tile (C.is_warning <> C.notification <> classes) article_ :: forall w i. Array HH.ClassName -> HH.HTML w i -> HH.HTML w i -> HH.HTML w i article_ classes head body = HH.article [HP.classes (C.message <> classes)] [ HH.div [HP.classes C.message_header] [head] , HH.div [HP.classes C.message_body ] [body] ] article :: forall w i. HH.HTML w i -> HH.HTML w i -> HH.HTML w i article head body = article_ [] head body error_message :: forall w i. HH.HTML w i -> HH.HTML w i -> HH.HTML w i error_message head body = article_ C.is_danger head body -- | Basic input field with a read-only side text. -- | -- |``` -- |div [field is-horizontal] -- | div [field-label normal] -- | label [label for-id] -- | text -- | div [field-body] -- | div [has-addons field] -- | p [control] -- | input -- | p [control] -- | a [button is-small is-static] -- | text -- |``` input_with_side_text :: forall w i. String -> String -> String -> (String -> i) -> String -> String -> HH.HTML w i input_with_side_text id title placeholder action value sidetext = HH.div [HP.classes $ C.field <> C.is_horizontal] [ HH.div [ HP.classes (C.field_label <> C.normal) ] [HH.label [ HP.classes C.label, HP.for id ] [ HH.text title ]] , HH.div [ HP.classes C.field_body ] [ HH.div [ HP.classes $ C.has_addons <> C.field ] [ HH.p [HP.classes C.control] [ HH.input $ [ HE.onValueInput action , HP.value value , HP.placeholder placeholder , HP.classes $ input_classes , HP.id id ] ] , HH.p [HP.classes C.control] [ HH.a [HP.classes $ C.button <> C.is_small <> C.is_static] [HH.text sidetext] ] ] ] ] -- | `modal`: create a modal by providing a few things: -- | - a title (a simple String) -- | - a body (`HTML` content) -- | - a footer (`HTML` content) modal :: forall w i. String -> Array (HH.HTML w i) -> Array (HH.HTML w i) -> HH.HTML w i modal title body foot = modal_ [ modal_background , modal_card_large [modal_header title, modal_body body] , modal_foot foot ] -- selection: create a "select" input. -- Get the changes with "onSelectedIndexChange" which provides an index. selection :: forall w i. (Int -> i) -> Array String -> String -> HH.HTML w i selection action values selected = HH.div [HP.classes $ C.select <> C.is_normal] [ HH.select [ HE.onSelectedIndexChange action ] $ map (\n -> HH.option [HP.value n, HP.selected (n == selected)] [HH.text n]) values ] selection_field :: forall w i. String -> String -> (Int -> i) -> Array String -> String -> HH.HTML w i selection_field id title action values selected = field_entry id title $ selection action values selected selection_field' :: forall w i. String -> String -> (Int -> i) -> Array (Tuple String String) -> String -> HH.HTML w i selection_field' id title action values selected = field_entry id title $ selection' action values selected selection_field'' :: forall w i t. Show t => String -> String -> (Int -> i) -> Array (Tuple String String) -> t -> Maybe t -> HH.HTML w i selection_field'' id title action values default_value selected = field_entry id title $ selection' action values selected_value where selected_value = (show $ fromMaybe default_value selected) -- | selection': as `selection` but takes an array of tuple as values. -- | First value in the tuple is what to display, the second one is what to match on. selection' :: forall w i. (Int -> i) -> Array (Tuple String String) -> String -> HH.HTML w i selection' action values selected = HH.div [HP.classes $ C.select <> C.is_normal] [ HH.select [ HE.onSelectedIndexChange action ] $ map (\n -> HH.option [HP.value (snd n), HP.selected ((snd n) == selected)] [HH.text (fst n)]) values ] tag_light_info :: forall w i. String -> HH.HTML w i tag_light_info str = HH.span [HP.classes (C.tag <> C.is_info <> C.is_light)] [HH.text str] div_large_content :: forall w i. Array (HH.HTML w i) -> HH.HTML w i div_large_content content = HH.div [HP.classes (C.is_large <> C.content)] content div_content :: forall w i. Array HH.ClassName -> Array (HH.HTML w i) -> HH.HTML w i div_content classes content = HH.div [HP.classes (C.content <> classes)] content explanation :: forall w i. Array (HH.HTML w i) -> HH.HTML w i explanation content = HH.blockquote [HP.classes [HH.ClassName "justified"]] content quote :: forall w i. Array (HH.HTML w i) -> HH.HTML w i quote content = div_content [] [ explanation content ] simple_quote :: forall w i. String -> HH.HTML w i simple_quote content = quote [ p content ] tabs :: forall w i. Array HH.ClassName -> Array (HH.HTML w i) -> HH.HTML w i tabs classes tab_list = HH.div [HP.classes $ C.tabs <> classes] [HH.ul_ tab_list] fancy_tabs :: forall w i. Array (HH.HTML w i) -> HH.HTML w i fancy_tabs arr = tabs (C.is_medium <> C.is_boxed <> C.is_centered) arr tab_entry :: forall w i. Boolean -> String -> i -> HH.HTML w i tab_entry active name action = HH.li (if active then [HP.classes C.is_active] else []) [ HH.a [HE.onClick \_ -> action] [HH.text name] ] delete_btn :: forall w i. i -> HH.HTML w i delete_btn action = HH.button [HE.onClick \_ -> action, HP.classes C.delete] [] notification :: forall w i. Array HH.ClassName -> String -> i -> HH.HTML w i notification classes value deleteaction = HH.div [HP.classes (C.notification <> classes)] [ delete_btn deleteaction , HH.text value ] notification_primary :: forall w i. String -> i -> HH.HTML w i notification_primary value action = notification C.is_primary value action notification_success :: forall w i. String -> i -> HH.HTML w i notification_success value action = notification C.is_success value action notification_warning :: forall w i. String -> i -> HH.HTML w i notification_warning value action = notification C.is_warning value action notification_danger :: forall w i. String -> i -> HH.HTML w i notification_danger value action = notification C.is_danger value action notification_block' :: forall w i. Array HH.ClassName -> Array (HH.HTML w i) -> HH.HTML w i notification_block' classes content = HH.div [HP.classes (C.notification <> classes)] content notification' :: forall w i. Array HH.ClassName -> String -> HH.HTML w i notification' classes value = HH.div [HP.classes (C.notification <> classes)] [ HH.text value ] notification_primary' :: forall w i. String -> HH.HTML w i notification_primary' value = notification' C.is_primary value notification_warning' :: forall w i. String -> HH.HTML w i notification_warning' value = notification' C.is_warning value notification_danger' :: forall w i. String -> HH.HTML w i notification_danger' value = notification' C.is_danger value notification_danger_block' :: forall w i. Array (HH.HTML w i) -> HH.HTML w i notification_danger_block' content = notification_block' C.is_danger content btn_validation_ :: forall w i. String -> HH.HTML w i btn_validation_ str = HH.button -- [ HP.style "padding: 0.5rem 1.25rem;" [ HP.type_ HP.ButtonSubmit , HP.classes $ C.button <> C.is_primary ] [ HH.text str ] btn_validation :: forall w i. HH.HTML w i btn_validation = btn_validation_ "Validate" -- | Box with tags. -- |``` -- |box_with_tag C.has_background_danger_light some_tag [Bulma.p "Hello"] -- |``` box_with_tag :: forall w action. Array HH.ClassName -- css classes (like the color) -> HH.HTML w action -- tag (title for the box) -> Array (HH.HTML w action) -- box content -> HH.HTML w action box_with_tag colors tag xs = box_ (C.no_padding_left <> C.no_padding_top <> colors) [tag, HH.div [HP.classes $ C.restore_padding_left <> C.restore_padding_top] xs]