@@ -106,6 +106,9 @@ display :: (MonadWidget t m, Show a) => Dynamic t a -> m ()
106106display a = dynText =<< mapDyn show a
107107
108108--TODO: Should this be renamed to 'widgetView' for consistency with 'widgetHold'?
109+-- | Given a Dynamic of widget-creating actions, create a widget that is recreated whenever the Dynamic updates.
110+-- The returned Event of widget results occurs when the Dynamic does.
111+-- Note: Often, the type 'a' is an Event, in which case the return value is an Event-of-Events that would typically be flattened.
109112dyn :: MonadWidget t m => Dynamic t (m a) -> m (Event t a)
110113dyn child = do
111114 startPlaceholder <- text' ""
@@ -133,6 +136,9 @@ dyn child = do
133136 build newChild
134137 return $ fmap fst newChildBuilt
135138
139+-- | Given an initial widget and an Event of widget-creating actions, create a widget that is recreated whenever the Event fires.
140+-- The returned Dynamic of widget results occurs when the Event does.
141+-- Note: Often, the type 'a' is an Event, in which case the return value is a Dynamic-of-Events that would typically be flattened.
136142widgetHold :: MonadWidget t m => m a -> Event t (m a) -> m (Dynamic t a)
137143widgetHold child0 newChild = do
138144 startPlaceholder <- text' ""
@@ -162,7 +168,11 @@ widgetHold child0 newChild = do
162168 holdDyn result0 $ fmap fst newChildBuilt
163169
164170--TODO: Something better than Dynamic t (Map k v) - we want something where the Events carry diffs, not the whole value
165−listWithKey :: (Ord k, MonadWidget t m) => Dynamic t (Map k v) -> (k -> Dynamic t v -> m a) -> m (Dynamic t (Map k a))
171+-- | Create a dynamically-changing set of widgets from a Dynamic key/value map.
172+listWithKey :: (Ord k, MonadWidget t m)
173+ => Dynamic t (Map k v) -- ^ Dynamic key/value map
174+ -> (k -> Dynamic t v -> m a) -- ^ Function to create a widget for a given key from Dynamic value
175+ -> m (Dynamic t (Map k a)) -- ^ Dynamic map from keys to widget results
166176listWithKey vals mkChild = do
167177 doc <- askDocument
168178 endPlaceholder <- text' ""
@@ -211,7 +221,12 @@ listWithKey vals mkChild = do
211221 postBuild
212222 holdDyn Map.empty $ fmap (fmap (fst . fst)) newChildren
213223
214−listWithKey' :: forall t m k v a. (Ord k, MonadWidget t m) => Map k v -> Event t (Map k (Maybe v)) -> (k -> v -> Event t v -> m a) -> m (Dynamic t (Map k a))
224+-- | Create a dynamically-changing set of widgets from a key/value map with update Events.
225+listWithKey' :: forall t m k v a. (Ord k, MonadWidget t m)
226+ => Map k v -- ^ Initial key/value map
227+ -> Event t (Map k (Maybe v)) -- ^ Event of map updates
228+ -> (k -> v -> Event t v -> m a) -- ^ Function to create a widget for a given key from initial value and update Event
229+ -> m (Dynamic t (Map k a)) -- ^ Dynamic map from keys to widget results
215230listWithKey' initialVals valsChanged mkChild = do
216231 doc <- askDocument
217232 endPlaceholder <- text' ""
@@ -267,6 +282,8 @@ listWithKey' initialVals valsChanged mkChild = do
267282 mapDyn (fmap (fst . fst)) children
268283
269284--TODO: Something better than Dynamic t (Map k v) - we want something where the Events carry diffs, not the whole value
285+-- | Create a dynamically-changing set of Event-valued widgets.
286+-- This is like listWithKey, specialized for widgets returning (Event t a). listWithKey would return 'Dynamic t (Map k (Event t a))' in this scenario, but listViewWithKey flattens this to 'Event t (Map k a)' via 'switch'.
270287listViewWithKey :: (Ord k, MonadWidget t m) => Dynamic t (Map k v) -> (k -> Dynamic t v -> m (Event t a)) -> m (Event t (Map k a))
271288listViewWithKey vals mkChild = liftM (switch . fmap mergeMap) $ listViewWithKey' vals mkChild
272289
@@ -321,7 +338,12 @@ listViewWithKey' vals mkChild = do
321338
322339--TODO: Deduplicate the various list*WithKey* implementations
323340
324−selectViewListWithKey_ :: forall t m k v a. (MonadWidget t m, Ord k) => Dynamic t k -> Dynamic t (Map k v) -> (k -> Dynamic t v -> Dynamic t Bool -> m (Event t a)) -> m (Event t k)
341+-- | Create a dynamically-changing set of widgets, one of which is selected at any time.
342+selectViewListWithKey_ :: forall t m k v a. (MonadWidget t m, Ord k)
343+ => Dynamic t k -- ^ Current selection key
344+ -> Dynamic t (Map k v) -- ^ Dynamic key/value map
345+ -> (k -> Dynamic t v -> Dynamic t Bool -> m (Event t a)) -- ^ Function to create a widget for a given key from Dynamic value and Dynamic Bool indicating if this widget is currently selected
346+ -> m (Event t k) -- ^ Event that fires when any child's return Event fires. Contains key of an arbitrary firing widget.
325347selectViewListWithKey_ selection vals mkChild = do
326348 let selectionDemux = demux selection -- For good performance, this value must be shared across all children
327349 selectChild <- listWithKey vals $ \k v -> do
@@ -676,9 +698,12 @@ elClass elementTag c child = elAttr elementTag ("class" =: c) child
676698-- Copied and pasted from Reflex.Widget.Class
677699--------------------------------------------------------------------------------
678700
701+-- | Create a dynamically-changing set of widgets from a Dynamic key/value map.
702+-- Unlike the 'withKey' variants, the child widgets are insensitive to which key they're associated with.
679703list :: (MonadWidget t m, Ord k) => Dynamic t (Map k v) -> (Dynamic t v -> m a) -> m (Dynamic t (Map k a))
680704list dm mkChild = listWithKey dm (\_ dv -> mkChild dv)
681705
706+-- | Create a dynamically-changing set of widgets from a Dynamic list.
682707simpleList :: MonadWidget t m => Dynamic t [v] -> (Dynamic t v -> m a) -> m (Dynamic t [a])
683708simpleList xs mkChild = mapDyn (map snd . Map.toList) =<< flip list mkChild =<< mapDyn (Map.fromList . zip [(1::Int)..]) xs
684709
@@ -759,7 +784,13 @@ dtdd h w = do
759784blank :: forall t m. MonadWidget t m => m ()
760785blank = return ()
761786
762−tableDynAttr :: forall t m r k v. (MonadWidget t m, Show k, Ord k) => String -> [(String, k -> Dynamic t r -> m v)] -> Dynamic t (Map k r) -> (k -> m (Dynamic t (Map String String))) -> m (Dynamic t (Map k (El t, [v])))
787+-- | A widget to display a table with static columns and dynamic rows.
788+tableDynAttr :: forall t m r k v. (MonadWidget t m, Show k, Ord k)
789+ => String -- ^ Class applied to <table> element
790+ -> [(String, k -> Dynamic t r -> m v)] -- ^ Columns of (header, row key -> row value -> child widget)
791+ -> Dynamic t (Map k r) -- ^ Map from row key to row value
792+ -> (k -> m (Dynamic t (Map String String))) -- ^ Function to compute <tr> element attributes from row key
793+ -> m (Dynamic t (Map k (El t, [v]))) -- ^ Map from row key to (El, list of widget return values)
763794tableDynAttr klass cols dRows rowAttrs = elAttr "div" (Map.singleton "style" "zoom: 1; overflow: auto; background: white;") $ do
764795 elAttr "table" (Map.singleton "class" klass) $ do
765796 el "thead" $ el "tr" $ do
@@ -770,7 +801,14 @@ tableDynAttr klass cols dRows rowAttrs = elAttr "div" (Map.singleton "style" "zo
770801 elDynAttr' "tr" dAttrs $ mapM (\x -> el "td" $ snd x k r) cols)
771802
772803--TODO preselect a tab on open
773−tabDisplay :: forall t m k. (MonadFix m, MonadWidget t m, Show k, Ord k) => String -> String -> Map k (String, m ()) -> m ()
804+-- | A widget to construct a tabbed view that shows only one of its child widgets at a time.
805+-- Creates a header bar containing a <ul> with one <li> per child; clicking a <li> displays
806+-- the corresponding child and hides all others.
807+tabDisplay :: forall t m k. (MonadFix m, MonadWidget t m, Show k, Ord k)
808+ => String -- ^ Class applied to <ul> element
809+ -> String -- ^ Class applied to currently active <li> element
810+ -> Map k (String, m ()) -- ^ Map from (arbitrary) key to (tab label, child widget)
811+ -> m ()
774812tabDisplay ulClass activeClass tabItems = do
775813 rec dCurrentTab <- holdDyn Nothing (updated dTabClicks)
776814 dTabClicks :: Dynamic t (Maybe k) <- elAttr "ul" (Map.singleton "class" ulClass) $ do