1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//! Exposes the layout's available width to the application (RFC-046).
//!
//! `AppLayout` is an application shell — header, sidebar, body, footer —
//! and adapting that composition to available width is close to the
//! definition of what a shell does. Before this, snora had **no
//! window-size awareness of any kind**: an application wanting
//! breakpoints had to write window observation itself.
//!
//! # Exposure, not behavior
//!
//! [`responsive_render`] prescribes nothing: it hands the application a
//! width and lets it build whatever `AppLayout` it wants from that. There
//! is no `Breakpoint` type, no threshold, no auto-collapse — those decide
//! *for* the application, which is exactly the kind of decision snora has
//! consistently declined (no theming layer, no form widgets, no
//! prescribed layout beyond the skeleton itself). The application decides
//! its own thresholds and what changes at them; snora supplies the
//! number.
//!
//! # `f32` width, not `Size` (RFC-046 Q-2)
//!
//! Width is what the downstream request actually asked for, and is the
//! narrower contract — `iced::widget::Responsive`'s closure receives the
//! full `Size`, but only `.width` is threaded through here. Height would
//! cost nothing extra to also expose, but RFC-046 asks for a decision
//! stated plainly rather than defaulting to "give them everything the
//! widget happens to have" — narrowing to what was asked for is the
//! chosen answer; see the review request for the full reasoning.
//!
//! # Reuses the existing z-stack — does not duplicate it
//!
//! [`responsive_render`]'s closure calls [`crate::render::render`]
//! directly — the same public entry point applications call today. There
//! is no second copy of the layer-composition logic; RFC-039 already
//! extracted the shared path this reuses.
use Responsive;
use ;
use AppLayout;
/// Renders an [`AppLayout`] that may depend on the available width.
///
/// `build` receives the width available to the layout (in logical
/// pixels) and returns the `AppLayout` to render at that width. It may
/// be called again whenever the available size changes — see
/// [`iced::widget::Responsive`]'s own documentation for the underlying
/// mechanism.
///
/// A sibling to [`crate::render::render`], not a replacement — this is
/// engine capability, not `design`-gated, so it lives in the default
/// surface next to `render`. Applications not calling this entry point
/// are unaffected; `render`'s own behavior and signature are unchanged.
///
/// ```rust,ignore
/// use snora::{AppLayout, responsive_render};
///
/// fn view(state: &State) -> Element<'_, Message> {
/// responsive_render(move |width| {
/// let layout = AppLayout::new(body(state));
/// if width < 600.0 {
/// layout // application's own choice: no sidebar below 600px
/// } else {
/// layout.side_bar(sidebar(state))
/// }
/// })
/// }
/// ```