snora/lib.rs
1//! # snora
2//!
3//! The iced engine for the Snora GUI framework.
4//!
5//! This crate binds [`snora_core`] vocabulary to iced. It exposes a single
6//! entry point, [`render`], a toast lifecycle helper module, and — when
7//! the `widgets` feature is enabled (the default) — a re-exported set of
8//! prefab `iced::Element` builders from the [`snora-widgets`] crate.
9//!
10//! # Layering
11//!
12//! ```text
13//! Your application
14//! │
15//! ▼
16//! snora::render(AppLayout<Element, Message>) -> Element
17//! │
18//! ├─► snora-widgets (optional, prefab UI parts)
19//! │ │
20//! │ ▼
21//! │ snora-design (optional, design tokens — no iced dependency)
22//! ▼
23//! snora-core (vocabulary: Toast, Dialog, Sheet, SheetSize, …)
24//! ```
25//!
26//! The dependency graph above is strict and the only way crates relate
27//! to each other:
28//!
29//! * `snora-core` has zero iced dependency. It owns the vocabulary
30//! (what choices exist).
31//! * `snora-design` has zero iced dependency. It owns the opt-in design
32//! token vocabulary (`Tokens`, `Palette`, contrast utilities).
33//! * `snora-widgets` depends on `snora-core`, `iced`, and (behind the
34//! `design` feature) `snora-design`. It owns the prefab widget visuals
35//! and the iced style bridge that turns tokens into `iced::*::Style`.
36//! * `snora` depends on `snora-core` and (optionally) `snora-widgets`
37//! and `snora-design`. It owns the engine — `render`, the layer
38//! composition, and the toast lifecycle helpers.
39//!
40//! Applications normally only depend on `snora` and use it as the single
41//! umbrella crate; the workspace split exists so each layer can evolve
42//! at its own pace.
43//!
44//! # A minimal application view
45//!
46//! ```ignore
47//! use iced::{Element, widget::text};
48//! use snora::{AppLayout, render, LayoutDirection};
49//!
50//! fn view(state: &MyState) -> Element<'_, Message> {
51//! let body: Element<'_, Message> = text("Hello, snora!").into();
52//!
53//! let layout = AppLayout::new(body)
54//! .direction(LayoutDirection::Ltr);
55//!
56//! render(layout)
57//! }
58//! ```
59//!
60//! # Engine-only builds
61//!
62//! Applications that supply 100 % of their UI parts and do not want the
63//! prefab widgets compiled in can opt out:
64//!
65//! ```toml
66//! [dependencies]
67//! snora = { version = "0.25", default-features = false }
68//! ```
69//!
70//! In this configuration `snora-widgets` is not pulled in and the
71//! `snora::widget` module does not exist.
72//!
73//! [`snora-widgets`]: https://docs.rs/snora-widgets
74
75#![warn(missing_docs)]
76#![cfg_attr(docsrs, feature(doc_cfg))]
77
78// ---- Re-export the vocabulary from snora-core --------------------------
79pub use snora_core::{
80 AppLayout, BreadcrumbAction, Crumb, Dialog, Edge, Icon, LayoutDirection, Menu, MenuAction,
81 MenuItem, Sheet, SheetEdge, SheetSize, SideBar, SideBarItem, Tab, TabAction, TabBar, Toast,
82 ToastIntent, ToastLifetime, ToastPosition,
83};
84
85// ---- Engine modules (always present) ----------------------------------
86/// Stable identifiers snora attaches to the surfaces it renders itself
87/// (RFC-047). Private module; the identifier reference page under
88/// `docs/src/reference/` is the public-facing form of this contract.
89mod identifiers;
90/// Keyboard dismissal helper: [`keyboard::dismiss_on_escape`].
91pub mod keyboard;
92mod overlay;
93/// The single rendering entry point: [`render`].
94pub mod render;
95/// Width-aware rendering: [`responsive::responsive_render`] (RFC-046).
96pub mod responsive;
97/// Toast rendering and lifecycle helpers
98/// ([`subscription`](toast::subscription), [`sweep_expired`](toast::sweep_expired)).
99pub mod toast;
100
101pub use render::render;
102pub use responsive::responsive_render;
103
104// ---- Widget re-exports (feature-gated) --------------------------------
105
106/// Direction-aware row helpers. Re-exported from `snora-widgets`.
107#[cfg(feature = "widgets")]
108pub use snora_widgets::direction;
109
110/// Shared style functions used by the prefab widgets.
111/// Re-exported from `snora-widgets`.
112#[cfg(feature = "widgets")]
113pub use snora_widgets::style;
114
115/// Optional prefab `iced::Element` builders for header / sidebar / footer
116/// / menu / icon. Re-exported from `snora-widgets`.
117///
118/// This module is only available when the `widgets` feature is enabled
119/// (which is the default).
120#[cfg(feature = "widgets")]
121pub mod widget;
122
123/// Convenience re-export of Lucide icon constants. Available when both
124/// `widgets` and `lucide-icons` features are enabled.
125#[cfg(all(feature = "widgets", feature = "lucide-icons"))]
126pub use snora_widgets::lucide;
127
128// ---- Design re-exports (feature-gated) --------------------------------
129
130/// Snora Design token types, iced style bridge, and contrast utilities.
131///
132/// Available when the `design` feature is enabled. Exposes:
133///
134/// * Token vocabulary from [`snora_design`]: [`design::Tokens`],
135/// [`design::Palette`], [`design::Color`], and the full variant /
136/// sub-token set.
137/// * The iced style bridge under [`design::style`]: color conversion,
138/// semantic button styles, and card/container styles.
139/// * Shallow UI primitives: [`design::button`], [`design::card`],
140/// [`design::notice`], [`design::chip`], [`design::progress`].
141/// * Pure-Rust WCAG contrast utilities under [`design::contrast`]:
142/// [`design::contrast::relative_luminance`],
143/// [`design::contrast::contrast_ratio`],
144/// [`design::contrast::composite_over`].
145///
146/// # iced 0.14 focus limitation
147///
148/// Standard `button` / `container` styles in iced 0.14 do not expose
149/// keyboard-focus state. The style bridge maps every status iced does expose
150/// (hover, pressed, disabled); custom focus rings on standard controls are
151/// not deliverable in v0.20 through this path. See RFC-025 and
152/// `docs/src/contributing/semantic-accessibility.md` for detail.
153#[cfg(feature = "design")]
154pub mod design;