I came to FRP in a functionall language (Haskell) so I am not sure how applicable my experience is.
Often, you can treat the stream element as an implementation detail. Where possible, you simply define the state of widget A to be a function of the state of widget B. Keeping in mind that this is implemented in terms of streams will tell you what function to use to make this specification. In this line of thinking, I often think of the system as a static network, where each node (representing a widget) is a pure function converting some inputs to output (or has no input and produce a constant output). A widget can also set its appearence based on its input.
When the user provides input to a widget (in this model), the corresponding node itself changes to produce a different output (giving you a new, static, graph). For simplicity, I will assume that all user-input widgets correspond to output only nodes.
For example, consider a netwwork, X, with node A corresponding to a textbox. A takes no input, and outputs the constant of the current value of the textbox. Imagine that we know what the value of the textbox will be at all times, and want to animate the entire window. To do this, we can stream in the values of the textbox, and let the network update itself. In this way the textbox is sending a stream of strings into the rest of the network.
Moving to a lower level, consider how the textbox itself is implemented. While we can think of it as output only (as I almost always do), it can be implemented as taking a stream of key-events, and outputing a stream of strings. At this level, I take an event driven perspective. While the textbox recieves a 'stream' of key-events, and outputs a 'stream' of strings, what really happens is that whenever there is a key event, the textbox receives it, and emits a string event, in the same way that you might have an onEvent() handler call onStringChange() in a traditioanl OO design.
In writing this, and re-reading your question, I think the key difference is that I do not view UI elements as a stream. Instead they are static object that streams pass through. As streams pass through them, they be update the stream or themselves.
Often, you can treat the stream element as an implementation detail. Where possible, you simply define the state of widget A to be a function of the state of widget B. Keeping in mind that this is implemented in terms of streams will tell you what function to use to make this specification. In this line of thinking, I often think of the system as a static network, where each node (representing a widget) is a pure function converting some inputs to output (or has no input and produce a constant output). A widget can also set its appearence based on its input.
When the user provides input to a widget (in this model), the corresponding node itself changes to produce a different output (giving you a new, static, graph). For simplicity, I will assume that all user-input widgets correspond to output only nodes.
For example, consider a netwwork, X, with node A corresponding to a textbox. A takes no input, and outputs the constant of the current value of the textbox. Imagine that we know what the value of the textbox will be at all times, and want to animate the entire window. To do this, we can stream in the values of the textbox, and let the network update itself. In this way the textbox is sending a stream of strings into the rest of the network.
Moving to a lower level, consider how the textbox itself is implemented. While we can think of it as output only (as I almost always do), it can be implemented as taking a stream of key-events, and outputing a stream of strings. At this level, I take an event driven perspective. While the textbox recieves a 'stream' of key-events, and outputs a 'stream' of strings, what really happens is that whenever there is a key event, the textbox receives it, and emits a string event, in the same way that you might have an onEvent() handler call onStringChange() in a traditioanl OO design.
In writing this, and re-reading your question, I think the key difference is that I do not view UI elements as a stream. Instead they are static object that streams pass through. As streams pass through them, they be update the stream or themselves.