teksilo-core 0.9.0

Core of the Teksilo GUI framework — widget trait, arena, layout engine, event dispatch, focus, signals and theming.
Documentation
// SPDX-License-Identifier: MPL-2.0
// SPDX-FileCopyrightText: 2026 FernTech

/// How focus was acquired — used for `:focus-visible` behavior.
/// Only show focus ring when focus was gained via keyboard, not pointer click.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FocusOrigin {
    /// Focus gained via Tab/Shift-Tab keyboard navigation.
    Keyboard,
    /// Focus gained via pointer click.
    Pointer,
    /// Focus set programmatically by the application.
    Programmatic,
}

/// Policy for a focus **traversal scope**, declared via the `FocusScope`
/// wrapper widget. Controls what Tab / Shift+Tab does when it reaches the
/// scope's ends.
///
/// A scope groups + scopes the `tab_index` numbering of its descendants:
/// two sibling scopes that both number their children `1, 2, 3` never
/// interleave — each scope is an independent, ordered unit within its
/// parent. This is Teksilo's analogue of Flutter `FocusTraversalGroup` /
/// WPF `KeyboardNavigation.TabNavigation`.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TraversalScopePolicy {
    /// Tab flows *out* of the scope at its ends into the enclosing scope's
    /// next member. The scope groups `tab_index` numbering without trapping
    /// focus — use for logical regions in a continuous Tab order (e.g. dock
    /// panels, where each panel numbers its own controls without colliding
    /// with sibling panels).
    Continue,
    /// Tab *wraps* within the scope and never exits via keyboard navigation.
    /// Use for modal dialogs — the one surface whose pattern (ARIA's Dialog
    /// (Modal)) actually calls for containing focus.
    ///
    /// **Not for popovers or menus.** Those implement Disclosure and Menu,
    /// which mandate the opposite: Tab is an exit gesture there, and the
    /// framework already answers it by dismissing the overlay focus leaves
    /// rather than by trapping focus inside it. Wrapping such an overlay in a
    /// `Cycle` scope defeats that — focus can no longer leave, so the
    /// dismissal never fires and the panel becomes keyboard-inescapable except
    /// via Escape.
    Cycle,
}