use-interaction 0.1.0

Interaction state primitives for RustUse UI
Documentation
#![forbid(unsafe_code)]
#![doc = include_str!("../README.md")]

/// Common UI interaction states.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub enum InteractionState {
    Idle,
    Hovered,
    Focused,
    Active,
    Disabled,
    Selected,
    Loading,
    Pressed,
    Expanded,
    Collapsed,
}

impl InteractionState {
    pub fn is_interactive(self) -> bool {
        !matches!(self, Self::Disabled | Self::Loading)
    }

    pub fn is_disabled(self) -> bool {
        matches!(self, Self::Disabled)
    }

    pub fn is_focus_visible_candidate(self) -> bool {
        matches!(self, Self::Focused | Self::Active | Self::Pressed)
    }
}

/// Input source or interaction channel.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub enum InteractionKind {
    Pointer,
    Keyboard,
    Touch,
    Voice,
    Programmatic,
}

/// User-facing intent for an interaction.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub enum InteractionIntent {
    Primary,
    Secondary,
    Destructive,
    Confirm,
    Cancel,
    Navigate,
    Disclose,
}

impl InteractionIntent {
    pub fn is_committal(self) -> bool {
        matches!(self, Self::Primary | Self::Destructive | Self::Confirm)
    }
}

#[cfg(test)]
mod tests {
    use super::{InteractionIntent, InteractionKind, InteractionState};

    #[test]
    fn constructs_interaction_enums() {
        assert_eq!(InteractionKind::Keyboard, InteractionKind::Keyboard);
        assert_eq!(InteractionIntent::Cancel, InteractionIntent::Cancel);
    }

    #[test]
    fn checks_interaction_state_helpers() {
        assert!(InteractionState::Focused.is_interactive());
        assert!(!InteractionState::Disabled.is_interactive());
        assert!(InteractionState::Disabled.is_disabled());
        assert!(InteractionState::Focused.is_focus_visible_candidate());
        assert!(InteractionState::Pressed.is_focus_visible_candidate());
        assert!(!InteractionState::Hovered.is_focus_visible_candidate());
        assert!(InteractionIntent::Confirm.is_committal());
        assert!(!InteractionIntent::Cancel.is_committal());
    }
}