#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
pub enum CollapsiblePosition {
#[default]
Left,
Right,
}
#[derive(Clone, PartialEq, Debug)]
pub struct CollapsibleState {
pub title: String,
pub expanded: bool,
pub collapsible: bool,
pub position: CollapsiblePosition,
pub width: u32,
pub class: String,
}
impl CollapsibleState {
pub fn new(title: String) -> Self {
Self {
title,
expanded: false,
collapsible: true,
position: CollapsiblePosition::default(),
width: 300,
class: String::new(),
}
}
pub fn with_expanded(mut self, expanded: bool) -> Self {
self.expanded = expanded;
self
}
pub fn with_collapsible(mut self, collapsible: bool) -> Self {
self.collapsible = collapsible;
self
}
pub fn with_position(mut self, position: CollapsiblePosition) -> Self {
self.position = position;
self
}
pub fn with_width(mut self, width: u32) -> Self {
self.width = width;
self
}
pub fn with_class(mut self, class: impl Into<String>) -> Self {
self.class = class.into();
self
}
pub fn toggle(&mut self) {
if self.collapsible {
self.expanded = !self.expanded;
}
}
pub fn position_class(&self) -> &'static str {
match self.position {
CollapsiblePosition::Left => "hi-collapsible-left",
CollapsiblePosition::Right => "hi-collapsible-right",
}
}
pub fn state_class(&self) -> &'static str {
if self.expanded {
"hi-collapsible-expanded"
} else {
"hi-collapsible-collapsed"
}
}
}
impl Default for CollapsibleState {
fn default() -> Self {
Self::new(String::new())
}
}
#[derive(Clone, PartialEq, Debug)]
pub struct CollapsibleChangeEvent {
pub expanded: bool,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_collapsible_state_new() {
let state = CollapsibleState::new("Test".to_string());
assert_eq!(state.title, "Test");
assert!(!state.expanded);
assert!(state.collapsible);
assert_eq!(state.width, 300);
}
#[test]
fn test_collapsible_toggle() {
let mut state = CollapsibleState::new("Test".to_string());
assert!(!state.expanded);
state.toggle();
assert!(state.expanded);
state.toggle();
assert!(!state.expanded);
}
#[test]
fn test_collapsible_toggle_when_not_collapsible() {
let mut state = CollapsibleState::new("Test".to_string());
state.collapsible = false;
state.expanded = false;
state.toggle();
assert!(!state.expanded); }
#[test]
fn test_position_class() {
let state = CollapsibleState::new("Test".to_string());
assert_eq!(state.position_class(), "hi-collapsible-left");
let state = state.with_position(CollapsiblePosition::Right);
assert_eq!(state.position_class(), "hi-collapsible-right");
}
#[test]
fn test_builder_pattern() {
let state = CollapsibleState::new("Settings".to_string())
.with_expanded(true)
.with_width(400)
.with_position(CollapsiblePosition::Right)
.with_class("custom-class");
assert_eq!(state.title, "Settings");
assert!(state.expanded);
assert_eq!(state.width, 400);
assert_eq!(state.position, CollapsiblePosition::Right);
assert_eq!(state.class, "custom-class");
}
}