Skip to main content

vtcode_ui/design/
constants.rs

1//! Shared design constants: ellipses, layout breakpoints, spacing tokens.
2//!
3//! These constants are the single source of truth for UI values that were
4//! previously scattered across multiple crates.
5
6/// Unicode ellipsis character as a string (`\u{2026}`).
7pub const ELLIPSIS: &str = "\u{2026}";
8
9/// Unicode ellipsis character.
10pub(crate) const ELLIPSIS_CHAR: char = '\u{2026}';
11
12/// Three-dot ASCII fallback ellipsis.
13pub(crate) const ELLIPSIS_ASCII: &str = "...";
14
15/// Alias used by preview contexts. Delegates to [`ELLIPSIS`].
16pub(crate) const INLINE_PREVIEW_ELLIPSIS: &str = ELLIPSIS;
17
18// ── Layout breakpoints ──────────────────────────────────────────────────────
19
20/// Maximum column width for compact layout mode.
21pub(crate) const COMPACT_MAX_COLS: u16 = 80;
22
23/// Maximum row height for compact layout mode.
24pub(crate) const COMPACT_MAX_ROWS: u16 = 20;
25
26/// Minimum column width for wide layout mode.
27pub(crate) const WIDE_MIN_COLS: u16 = 120;
28
29/// Minimum row height for wide layout mode.
30pub(crate) const WIDE_MIN_ROWS: u16 = 24;
31
32// ── Spacing tokens ──────────────────────────────────────────────────────────
33
34/// Tight spacing (1 cell).
35pub const SPACING_TIGHT: u16 = 1;
36
37/// Normal spacing (2 cells).
38pub const SPACING_NORMAL: u16 = 2;
39
40/// Loose spacing (4 cells).
41pub const SPACING_LOOSE: u16 = 4;
42
43/// Target column width before a trailing `value` in list rows (settings,
44/// model capabilities). Shorter titles are padded so values line up.
45pub const VALUE_COL: usize = 28;
46
47// ── Group header chrome ───────────────────────────────────────────────────
48
49/// Anchor prefix for modal group headers (`» Title`).
50/// Reuses the tracker current-task marker so section headings and focused
51/// rows read as one system on plain terminals.
52pub const GROUP_HEADER_ANCHOR: &str = "» ";
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn ellipsis_is_unicode() {
60        assert_eq!(ELLIPSIS, "\u{2026}");
61        assert_eq!(ELLIPSIS.chars().count(), 1);
62        assert_eq!(ELLIPSIS.len(), 3); // UTF-8: 3 bytes
63    }
64
65    #[test]
66    fn ellipsis_char_matches_string() {
67        assert_eq!(ELLIPSIS_CHAR, '\u{2026}');
68        assert_eq!(ELLIPSIS_CHAR.to_string(), ELLIPSIS);
69    }
70
71    #[test]
72    fn ellipsis_ascii_is_three_dots() {
73        assert_eq!(ELLIPSIS_ASCII, "...");
74        assert_eq!(ELLIPSIS_ASCII.len(), 3);
75    }
76
77    #[test]
78    fn preview_ellipsis_delegates() {
79        assert_eq!(INLINE_PREVIEW_ELLIPSIS, ELLIPSIS);
80    }
81
82    #[test]
83    fn layout_breakpoints_are_ordered() {
84        const _: () = assert!(COMPACT_MAX_COLS < WIDE_MIN_COLS);
85        const _: () = assert!(COMPACT_MAX_ROWS < WIDE_MIN_ROWS);
86    }
87
88    #[test]
89    fn spacing_tokens_are_ordered() {
90        const _: () = assert!(SPACING_TIGHT < SPACING_NORMAL);
91        const _: () = assert!(SPACING_NORMAL < SPACING_LOOSE);
92    }
93}