1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/// Line limit configuration for text fields.
///
/// Controls whether a text field allows multiple lines of input and how many
/// lines are visible at minimum and maximum.
///
/// # SingleLine
///
/// When `SingleLine` is used:
/// - Newline characters (`\n`) are blocked from input
/// - Pasted text has newlines replaced with spaces
/// - The text field scrolls horizontally if content exceeds width
/// - The Enter key does NOT insert a newline (may trigger submit action)
///
/// # MultiLine
///
/// When `MultiLine` is used:
/// - Newline characters are allowed
/// - The text field scrolls vertically if content exceeds visible lines
/// - `min_lines` controls minimum visible height (default: 1)
/// - `max_lines` controls maximum visible height before scrolling (default: unlimited)
///
/// # Example
///
/// ```
/// use cranpose_foundation::text::TextFieldLineLimits;
///
/// // Single-line text field (like a search box)
/// let single = TextFieldLineLimits::SingleLine;
///
/// // Multi-line with default settings
/// let multi = TextFieldLineLimits::default();
///
/// // Multi-line with 3-5 visible lines
/// let constrained = TextFieldLineLimits::MultiLine {
/// min_lines: 3,
/// max_lines: 5,
/// };
/// ```
/// Filters text for single-line mode by replacing newlines with spaces.
///
/// This is used when:
/// - Pasting text into a SingleLine text field
/// - Programmatically setting text on a SingleLine field
///
/// # Example
///
/// ```
/// use cranpose_foundation::text::filter_for_single_line;
///
/// assert_eq!(filter_for_single_line("hello\nworld"), "hello world");
/// assert_eq!(filter_for_single_line("a\n\nb"), "a b");
/// ```