diff --git a/src/App/Templates/Modal.purs b/src/App/Templates/Modal.purs index 2e114fd..c0ee50c 100644 --- a/src/App/Templates/Modal.purs +++ b/src/App/Templates/Modal.purs @@ -35,6 +35,7 @@ import App.Type.ResourceRecord as RR import App.DisplayErrors (error_to_paragraph, show_error_email) +type ActionCancelModal :: forall k. k -> k type ActionCancelModal i = i modal_rr_delete :: forall w i. Int -> (Int -> i) -> ActionCancelModal i -> HH.HTML w i modal_rr_delete rr_id action_remove_rr action_cancel_modal = Web.modal "Deleting a resource record" @@ -55,6 +56,7 @@ type ActionUpdateForm i = (Field.Field -> i) type ActionNewToken i = (RRId -> i) type ActionUpdateRR i = (RRUpdateValue -> i) type ActionValidateNewRR i = (AcceptedRRTypes -> i) +type ActionValidateLocalRR :: forall k. k -> k type ActionValidateLocalRR i = i current_rr_modal :: forall w i. Domain -> RRForm -> RRModal diff --git a/src/App/Templates/Table.purs b/src/App/Templates/Table.purs index 6351cc4..556f773 100644 --- a/src/App/Templates/Table.purs +++ b/src/App/Templates/Table.purs @@ -47,9 +47,9 @@ txt_name t owned_domains :: forall w i. Array DomainInfo -> (String -> i) -> (String -> i) -> (String -> i) -> (String -> i) -> HH.HTML w i owned_domains domains_i_exclusively_own action_enter_domain action_transfer_domain action_share_domain action_delete_domain = if A.length domains_i_exclusively_own > 0 - then Bulma.table [] [ owned_domains_table_header - , HH.tbody_ $ map owned_domain_row domains_i_exclusively_own - ] + then Web.table [] [ owned_domains_table_header + , HH.tbody_ $ map owned_domain_row domains_i_exclusively_own + ] else Bulma.p "No domain yet." where owned_domains_table_header :: HH.HTML w i @@ -72,9 +72,9 @@ owned_domains domains_i_exclusively_own action_enter_domain action_transfer_doma shared_domains :: forall w i. Array DomainInfo -> (String -> i) -> (String -> i) -> (String -> i) -> HH.HTML w i shared_domains domains_i_share action_enter_domain action_unshare_domain action_delete_domain = if A.length domains_i_share > 0 - then Bulma.table [] [ shared_domains_table_header - , HH.tbody_ $ map shared_domain_row domains_i_share - ] + then Web.table [] [ shared_domains_table_header + , HH.tbody_ $ map shared_domain_row domains_i_share + ] else Bulma.p "No domain yet." where shared_domains_table_header :: HH.HTML w i @@ -143,7 +143,7 @@ resource_records records action_create_or_update_rr action_delete_rr action_new_ -> Array (HH.HTML w i) rr_box colors title header dp rrs = if A.length rrs > 0 - then [ Bulma.box_with_tag colors title [Bulma.table_ [C.margin_left 3] [] [header, dp rrs]] ] + then [ Bulma.box_with_tag colors title [Web.table_ [C.margin_left 3] [] [header, dp rrs]] ] else [] --title_col_props = C.is 1 diff --git a/src/Bulma.purs b/src/Bulma.purs index 3e656de..63ab4f6 100644 --- a/src/Bulma.purs +++ b/src/Bulma.purs @@ -1,11 +1,8 @@ -- | The `Bulma` module is a wrapper around the BULMA css framework. module Bulma where -import Prelude (class Show, map, show, ($), (<>), (==)) +import Prelude (map, ($), (<>)) -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 @@ -15,15 +12,6 @@ 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, HP.type_ HP.InputCheckbox ] ] <> 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 ] @@ -41,15 +29,6 @@ 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] ] [ HH.text title ] - -h4 :: forall (w :: Type) (a :: Type). String -> HH.HTML w a -h4 title = HH.h4 [ HP.classes [C.title] ] [ 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.has_text_light, C.has_background_dark] ] @@ -67,15 +46,6 @@ hdiv = HH.div [ HP.classes [HH.ClassName "mt-5"] ] --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 - textarea_ :: forall w i. Array HH.ClassName -> String -> String -> (String -> i) -> HH.HTML w i textarea_ classes placeholder value action = HH.textarea @@ -97,117 +67,18 @@ level left right = HH.nav [ HP.classes [C.level] ] ] where itemize = map (\v -> HH.div [ HP.classes [C.level_item] ] [v]) --- | 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 ] - ] - 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] -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] ] @@ -295,58 +166,6 @@ 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] ] - ] - ] - ] - -side_text_above_input :: forall w i. - String -> String -> HH.HTML w i -> HH.HTML w i -side_text_above_input id title 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]] [ sidetext ] ] - ] - ] - -- | `modal`: create a modal by providing a few things: -- | - a title (a simple String) -- | - a body (`HTML` content) @@ -359,38 +178,6 @@ modal title body foot = , 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] @@ -409,60 +196,6 @@ 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 - -- | Box with tags. -- |``` -- |box_with_tag [C.has_background_danger_light] some_tag [Bulma.p "Hello"] @@ -479,20 +212,6 @@ box_with_tag colors tag xs -- GENERIC HTML API -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 ] - code :: forall w i. String -> HH.HTML w i code str = HH.code_ [ HH.text str ] @@ -505,9 +224,6 @@ 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 ] -option :: forall w i. String -> HH.HTML w i -option value = HH.option_ [HH.text value] - strong :: forall w i. String -> HH.HTML w i strong str = HH.strong_ [ HH.text str ] diff --git a/src/Web.purs b/src/Web.purs index 6ca5a48..726abf8 100644 --- a/src/Web.purs +++ b/src/Web.purs @@ -3,12 +3,24 @@ module Web ( module Bulma , module Web.Button + , module Web.Checkbox + , module Web.Field + , module Web.Header , module Web.Input + , module Web.Notification + , module Web.Table + , module Web.Tab , module Web.Tag ) where -import Web.Button -import Web.Input -import Web.Tag +import Web.Button (alert_btn, alert_btn_abbr, btn, btn_, btn_abbr, btn_abbr_, btn_add, btn_delete, btn_delete_ro, btn_modify, btn_modify_ro, btn_readonly, btn_ro, btn_save, btn_validation, btn_validation_, delete_btn) +import Web.Checkbox (checkbox) +import Web.Field (btn_labeled, div_field, div_field_, div_field_content, div_field_label, error_field_entry, field_entry, new_domain_field, option, select, selection, selection', selection_field, selection_field', selection_field'', side_text_above_input) +import Web.Header (h1, h3, h4) +import Web.Input (box_input, box_input_, box_password, box_password_, email_input, field_inner, input_classes, input_with_side_text, password_input, password_input_confirmation, password_input_new, render_input, token_input, username_input) +import Web.Notification (error_box, notification, notification', notification_block', notification_danger, notification_danger', notification_danger_block', notification_primary, notification_primary', notification_success, notification_warning, notification_warning') +import Web.Table (table, table_) +import Web.Tab (fancy_tabs, tab_entry, tabs) +import Web.Tag (tag, tag_ro, tags) import Bulma diff --git a/src/Web/Button.purs b/src/Web/Button.purs index 2cdb1fe..c883c11 100644 --- a/src/Web/Button.purs +++ b/src/Web/Button.purs @@ -15,6 +15,7 @@ module Web.Button , btn_save , btn_validation , btn_validation_ + , delete_btn ) where import Prelude (($), (<>)) @@ -93,3 +94,6 @@ 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 + +delete_btn :: forall w i. i -> HH.HTML w i +delete_btn action = HH.button [HE.onClick \_ -> action, HP.classes [C.delete]] [] diff --git a/src/Web/Checkbox.purs b/src/Web/Checkbox.purs new file mode 100644 index 0000000..6fe1341 --- /dev/null +++ b/src/Web/Checkbox.purs @@ -0,0 +1,17 @@ +module Web.Checkbox where + +import Prelude (($), (<>)) +import Halogen.HTML as HH +import Halogen.HTML.Properties as HP +import Halogen.HTML.Events as HE + +import CSSClasses as C + +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, HP.type_ HP.InputCheckbox ] ] <> content_ +-- diff --git a/src/Web/Div.purs b/src/Web/Div.purs new file mode 100644 index 0000000..dee8903 --- /dev/null +++ b/src/Web/Div.purs @@ -0,0 +1,8 @@ +module Web.Div where + +import Halogen.HTML as HH +import Halogen.HTML.Properties as HP + +import CSSClasses as C + + diff --git a/src/Web/Field.purs b/src/Web/Field.purs new file mode 100644 index 0000000..4b566d4 --- /dev/null +++ b/src/Web/Field.purs @@ -0,0 +1,136 @@ +module Web.Field where + +import Prelude (class Show, map, show, ($), (<>), (==)) + +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 CSSClasses as C + +-- | 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 + ] + +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 ] + +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) + +side_text_above_input :: forall w i. + String -> String -> HH.HTML w i -> HH.HTML w i +side_text_above_input id title 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]] [ sidetext ] ] + ] + ] + +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 ] + ] + +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] + +-- 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': 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 + ] + +option :: forall w i. String -> HH.HTML w i +option value = HH.option_ [HH.text value] diff --git a/src/Web/Form.purs b/src/Web/Form.purs new file mode 100644 index 0000000..d67036f --- /dev/null +++ b/src/Web/Form.purs @@ -0,0 +1,3 @@ +module Web.Form where + + diff --git a/src/Web/Header.purs b/src/Web/Header.purs new file mode 100644 index 0000000..74c8fd6 --- /dev/null +++ b/src/Web/Header.purs @@ -0,0 +1,15 @@ +module Web.Header where + +import Halogen.HTML as HH +import Halogen.HTML.Properties as HP + +import CSSClasses as C + +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] ] [ HH.text title ] + +h4 :: forall (w :: Type) (a :: Type). String -> HH.HTML w a +h4 title = HH.h4 [ HP.classes [C.title] ] [ HH.text title ] diff --git a/src/Web/Input.purs b/src/Web/Input.purs index 9bdcbb4..e87a476 100644 --- a/src/Web/Input.purs +++ b/src/Web/Input.purs @@ -1,21 +1,20 @@ -module Web.Input - ( email_input - , password_input - , password_input_confirmation - , password_input_new - , token_input - , username_input - ) where +module Web.Input where -import Prelude (($)) -import Bulma +import Prelude (($), (<>)) +import Web.Field import DOM.HTML.Indexed.AutocompleteType (AutocompleteType(..)) +import DOM.HTML.Indexed as DHI import Halogen.HTML as HH import Halogen.HTML.Properties as HP import Halogen.HTML.Events as HE +import CSSClasses as C + +input_classes :: Array HH.ClassName +input_classes = [C.input, C.is_small, C.is_info] + username_input :: forall w i. String -> String -> (String -> i) -> HH.HTML w i username_input title value action = div_field [] @@ -111,3 +110,75 @@ token_input title value action , HP.classes input_classes ] ] + +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) + +-- | 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] ] + ] + ] + ] + +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 ] + +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 diff --git a/src/Web/Notification.purs b/src/Web/Notification.purs new file mode 100644 index 0000000..65d8b4a --- /dev/null +++ b/src/Web/Notification.purs @@ -0,0 +1,53 @@ +module Web.Notification where + +import Prelude (($), (<>)) +import Web.Field + +import Halogen.HTML as HH +import Halogen.HTML.Properties as HP + +import CSSClasses as C +import Web.Button (delete_btn) + +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 + +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 diff --git a/src/Web/Tab.purs b/src/Web/Tab.purs new file mode 100644 index 0000000..7aaad17 --- /dev/null +++ b/src/Web/Tab.purs @@ -0,0 +1,21 @@ +module Web.Tab where + +import Prelude (($), (<>)) + +import Halogen.HTML as HH +import Halogen.HTML.Properties as HP +import Halogen.HTML.Events as HE + +import CSSClasses as C + + +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] ] diff --git a/src/Web/Table.purs b/src/Web/Table.purs new file mode 100644 index 0000000..69c5bd9 --- /dev/null +++ b/src/Web/Table.purs @@ -0,0 +1,15 @@ +module Web.Table where + +import Prelude ((<>), ($)) + +import Halogen.HTML as HH +import DOM.HTML.Indexed as DHI +import Halogen.HTML.Properties as HP + +import CSSClasses as C + +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