-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | HTML tables for Yesod
--   
--   HTML tables for Yesod
@package yesod-table
@version 2.0.3


-- | Table building library for yesod
--   
--   This library is intended to be brought in by a qualified import along
--   with type import as follows:
--   
--   <pre>
--   import qualified Yesod.Table as Table
--   import Yesod.Table (Table)
--   </pre>
--   
--   There are two types in this module: <a>Table</a> and <a>Column</a>.
--   Roughly, a <a>Table</a> is just a list of <a>Column</a>s. Except in
--   the case of rendering a <a>Table</a>, you should not need to use the
--   data constructors of either of these types. (In fact, you should not
--   need to refer to the type <a>Column</a> either). Instead, you should
--   use the functions <a>singleton</a>, <a>text</a>, <a>int</a>, etc. to
--   build singleton <a>Table</a>s (a <a>Table</a> with only one
--   <a>Column</a>) and use monoidal concatenation to combine these.
--   
--   It is important to note that, as defined in this library, <a>Table</a>
--   refers to a blueprint for an HTML table, not a complete table with
--   content.
--   
--   If you want to define your own table rendering function (and it's
--   likely that you will), then you will need the aforementioned data
--   constructors. You can look at the source of <a>buildBootstrap</a> for
--   an example of how to do this.
module Yesod.Table
newtype Table site a
Table :: (Seq (Column site a)) -> Table site a
data Column site a
Column :: !(WidgetT site IO ()) -> !(a -> WidgetT site IO ()) -> Column site a
[header] :: Column site a -> !(WidgetT site IO ())
[cell] :: Column site a -> !(a -> WidgetT site IO ())

-- | From a <a>Table</a> blueprint and a list of the data that it accepts,
--   build the actual html needed to visualize this data. This particular
--   rendering of the data applies the classes <tt>table</tt> and
--   <tt>table-striped</tt> to the <tt><a>table</a></tt> element. If you
--   are using bootstrap, this means that it will be formatted in the
--   bootstrap way. If not, the table will still render correctly, but the
--   classes will be renamed. I'm open to pull requests for supporting
--   other common table formats out of the box.
buildBootstrap :: Table site a -> [a] -> WidgetT site IO ()

-- | This is the most primitive and essential operation for building a
--   <a>Table</a>. All other table-building functions (such as
--   <a>widget</a>, <a>text</a>, and <a>linked</a>) build on top of
--   <a>singleton</a>. One common trend in the convenience functions is
--   that they accept <a>Text</a> as the table header. This is done because
--   I have found that it is uncommon to need the full power of HTML in the
--   header. Just know that if you need it, this function is the only way
--   to get it. The first argument is a widget that is the content to be
--   displayed in the table header. The second argument is the a function
--   that consumes a value to produce the content shown in a row of the
--   table body. These widgets need to be wrapped in a th/td if you are
--   using this function.
singleton :: WidgetT site IO () -> (a -> WidgetT site IO ()) -> Table site a

-- | This is the same as <a>singleton</a>, with the convenience of
--   accepting the table header as <a>Text</a>. It also wraps the header
--   widget in a th element and wraps the cell widget in a td element.
widget :: Text -> (a -> WidgetT site IO ()) -> Table site a

-- | This is the same as <a>widget</a>, but the table cell content it
--   produces is constant, meaning that the table cell in this column will
--   be the same for all rows.
const :: Text -> WidgetT site IO () -> Table site a

-- | Identical to <a>widget</a>, with the convenience of accepting the
--   table cell content as <a>Text</a>.
text :: Text -> (a -> Text) -> Table site a

-- | Identical to <a>widget</a>, with the convenience of accepting the
--   table cell content as <a>String</a>.
string :: Text -> (a -> String) -> Table site a

-- | Identical to <a>widget</a>, with the convenience of accepting the
--   table cell content as <a>ByteString</a>. If the <a>ByteString</a> is
--   not encoded as UTF8-encoded text, the cell will display text
--   indicating that non-text data was given.
bytestring :: Text -> (a -> ByteString) -> Table site a

-- | Identical to <a>widget</a>, with the convenience of accepting the
--   table cell content as any type with an instance of <a>Show</a>.
show :: (Show b) => Text -> (a -> b) -> Table site a

-- | Identical to <a>widget</a>, but allow to format the output with the
--   syntax of <a>printf</a> The datatype used must be an instance of
--   <a>PrintfArg</a>
printf :: (PrintfArg b) => Text -> String -> (a -> b) -> Table site a

-- | Identical to <a>widget</a>, with the convenience of accepting the
--   table cell content as <a>Int</a>.
int :: Text -> (a -> Int) -> Table site a

-- | Convenience function for building a plaintext link where the link text
--   and the route are determined by the row of data. If you are working
--   with an <tt>Entity</tt> (from <tt>persistent</tt>) and your foundation
--   type is named <tt>App</tt> you may want something like this:
--   
--   <pre>
--   myTable :: Table App (Entity Foo)
--   myTable = mempty
--     &lt;&gt; Table.linked "Name" (fooName . entityVal) (FooEditR . entityKey)
--     &lt;&gt; Table.int    "Size" (fooSize . entityVal)
--   </pre>
--   
--   This is the blueprint for a two-column table. The first column is a
--   link for editing the Foo, and the linked text is the <tt>Foo</tt>
--   name. The second column is just a number representing the size of the
--   <tt>Foo</tt> shown as plaintext.
linked :: Text -> (a -> Text) -> (a -> Route site) -> Table site a

-- | Prevents showing values in a <a>Table</a> if a condition is not met.
--   Example
--   
--   <pre>
--   myTable :: Table App Person
--   myTable = mempty
--     &lt;&gt; Table.text "Name" personName
--     &lt;&gt; Table.when (\p -&gt; personAge p &gt; 21) (Table.int "Age" personAge)
--   </pre>
--   
--   In this example, the table header Age will always show up with its
--   corresponding column, but any row for a person under 21 will have a
--   empty value for that column. The effect can be more profound:
--   
--   <pre>
--   myTable :: Table App Person
--   myTable = mempty
--     &lt;&gt; Table.text "Name" personName
--     &lt;&gt; Table.when (\p -&gt; personAge p &gt; 21) (mempty
--       &lt;&gt; Table.text "Favorite Color" personFavoriteColor
--       &lt;&gt; Table.text "Address" personAddress
--       &lt;&gt; Table.linked "Profile Page" (const "Profile") (ProfileR . personUsername)
--       )
--   </pre>
--   
--   This second example does not show information for any of the last
--   three columns if the person is under 21. The columns themselves though
--   are always present regardless of whether or not any values satisfy the
--   predicate.
when :: (a -> Bool) -> Table site a -> Table site a
whenWith :: WidgetT site IO () -> (a -> Bool) -> Table site a -> Table site a

-- | Promote a <a>Table</a> to take <a>Maybe</a> values. When the data
--   passed in matches the <a>Just</a> data constructor, the row is
--   presented as it would be with the original table. When it is
--   <a>Nothing</a>, the row is empty.
--   
--   As an example, imagine that in the data model for some application,
--   there exists a <tt>User</tt> and an <tt>Item</tt>. Each <tt>Item</tt>
--   can belong to either one or zero <tt>User</tt>s. We may build a table
--   as follows:
--   
--   <pre>
--   userTable :: Table site User
--   userTable = ...
--   
--   itemTable :: Table site Item
--   itemTable = ...
--   
--   itemWithUserTable :: Table site (Item, Maybe User)
--   itemWithUserTable = mconcat
--     [ contramap fst itemTable
--     , contramap snd (Table.maybe peopleTable)
--     ]
--   </pre>
maybe :: Table site a -> Table site (Maybe a)
maybeWith :: WidgetT site IO () -> Table site a -> Table site (Maybe a)

-- | This builds a multicolumn table. Here is an example of how this could
--   be used:
--   
--   <pre>
--   import Data.List (lookup)
--   import qualified Data.Text as Text
--   
--   data Color = Red | Green | Blue
--     deriving (Enum,Show,Bounded)
--   
--   data Age = Child | Teen | Adult | Elder
--     deriving (Enum,Show,Bounded)
--   
--   preferenceLevel :: Age -&gt; Color -&gt; WidgetT site IO ()
--   preferenceLevel age color = intToWidget $ fromMaybe 0 $ lookup (age,color)
--     [ ((Child,Red),   36), ((Child,Green, 10)), ((Teen,Green), 16)
--     , ((Teen,Blue),    8), ((Teen,Red),    31), ((Adult,Blue), 18)
--     , ((Adult,Green), 17), ((Elder,Blue),  41)
--     ]
--     where intToWidget :: Int -&gt; WidgetT site IO ()
--           intToWidget = toWidget . toHtml . Text.pack . show
--   
--   myTable :: Table App Color
--   myTable = mconcat
--     [ Table.text "" (Text.pack . show)
--     , Table.columns preferenceLevel (Text.pack . show) [minBound..maxBound]
--     ]
--   
--   myWidget :: WidgetT App IO ()
--   myWidget = Table.buildBootstrap myTable [minBound..maxBound]
--   </pre>
--   
--   The appearance of <tt>myWidget</tt> would be:
--   
--   <pre>
--         | Child | Teen | Adult | Elder
--   -------------------------------------
--   Red   |   36  |  31  |   0   |   0
--   Green |   10  |  16  |  17   |   0
--   Blue  |    0  |   8  |  18   |  41
--   </pre>
columns :: (b -> a -> WidgetT site IO ()) -> (b -> Text) -> [b] -> Table site a

-- | This function is identical to <a>columns</a> except that it does not
--   wrap the cell contents with <tt><a>th</a></tt> and <tt><a>td</a></tt>
--   for you.
columns' :: (b -> a -> WidgetT site IO ()) -> (b -> WidgetT site IO ()) -> [b] -> Table site a

-- | Then is roughly an if-then-else construct with the latter two clauses
--   (then and else) reversed. The name is taken from the <a>bool</a>
--   function in <a>Bool</a>.
bool :: Text -> (a -> Bool) -> (a -> WidgetT site IO ()) -> (a -> WidgetT site IO ()) -> Table site a
instance GHC.Base.Monoid (Yesod.Table.Table site a)
instance Data.Semigroup.Semigroup (Yesod.Table.Table site a)
instance Data.Functor.Contravariant.Contravariant (Yesod.Table.Table site)
instance Data.Functor.Contravariant.Divisible.Divisible (Yesod.Table.Table site)
instance Data.Functor.Contravariant.Contravariant (Yesod.Table.Column site)
