Skip to content

Commit 19ebc99

Browse files
committed
feat: add <br /> tag support and update examples
- Introduced a new <br /> tag for line breaks in JSX, enhancing readability and usability. - Updated multiple example components to utilize the <br /> tag instead of newline characters for better formatting. - Added a new BrDemo component to showcase the <br /> tag functionality.
1 parent cd808b8 commit 19ebc99

9 files changed

Lines changed: 129 additions & 55 deletions

File tree

src/br-demo.tsx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/// <reference path="./jsx.d.ts" />
2+
import React from 'react';
3+
import { createContainer } from './reconciler';
4+
5+
// Demo showcasing <br /> tag support
6+
const BrDemo: React.FC = () => {
7+
return (
8+
<>
9+
<b>Line Break Demo</b>
10+
<br />
11+
<br />
12+
This demonstrates the new <code>&lt;br /&gt;</code> tag support.
13+
<br />
14+
<br />
15+
<i>Benefits:</i>
16+
<br />
17+
• Cleaner JSX syntax
18+
<br />
19+
• More intuitive for React developers
20+
<br />
21+
• No more {'\\n'} strings
22+
<br />
23+
<br />
24+
<b>Example Usage:</b>
25+
<br />
26+
<pre>{`<b>Title</b>
27+
<br />
28+
<i>Subtitle</i>
29+
<br />
30+
<br />
31+
Content here...`}</pre>
32+
</>
33+
);
34+
};
35+
36+
// Create container and render
37+
const { render, container } = createContainer();
38+
render(<BrDemo />);
39+
40+
// Log the output
41+
setTimeout(() => {
42+
console.log('Line break demo output:');
43+
console.log(JSON.stringify(container.root, null, 2));
44+
}, 0);

src/example-bot.tsx

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ const CounterApp = () => {
99
return (
1010
<>
1111
<b>🔢 Counter Bot</b>
12-
{'\n\n'}
12+
<br />
13+
<br />
1314
<i>Current count: {count}</i>
14-
{'\n\n'}
15+
<br />
16+
<br />
1517
<row>
1618
<button onClick={() => setCount(c => c - 1)}>➖ Decrease</button>
1719
<button onClick={() => setCount(c => c + 1)}>➕ Increase</button>
@@ -30,18 +32,19 @@ const TodoApp = () => {
3032
return (
3133
<>
3234
<b>📝 Todo List</b>
33-
{'\n\n'}
35+
<br />
36+
<br />
3437
{todos.length === 0 ? (
3538
<i>No todos yet!</i>
3639
) : (
3740
todos.map((todo, i) => (
3841
<React.Fragment key={i}>
3942
{showCompleted ? <s>{todo}</s> : todo}
40-
{'\n'}
43+
<br />
4144
</React.Fragment>
4245
))
4346
)}
44-
{'\n'}
47+
<br />
4548
<row>
4649
<button onClick={() => setTodos([...todos, `Task ${todos.length + 1}`])}>
4750
➕ Add Task
@@ -69,27 +72,29 @@ const HelpApp = () => {
6972
return (
7073
<>
7174
<b>Text Formatting Examples</b>
72-
{'\n\n'}
75+
<br />
76+
<br />
7377
<b>Bold text</b>
74-
{'\n'}
78+
<br />
7579
<i>Italic text</i>
76-
{'\n'}
80+
<br />
7781
<u>Underlined text</u>
78-
{'\n'}
82+
<br />
7983
<s>Strikethrough</s>
80-
{'\n'}
84+
<br />
8185
<tg-spoiler>Hidden spoiler</tg-spoiler>
82-
{'\n'}
86+
<br />
8387
<code>inline code</code>
84-
{'\n\n'}
88+
<br />
89+
<br />
8590
<pre>
8691
{`function example() {
8792
return "Code block";
8893
}`}
8994
</pre>
90-
{'\n'}
95+
<br />
9196
<blockquote>This is a quote</blockquote>
92-
{'\n'}
97+
<br />
9398
<row>
9499
<button onClick={() => setSection('main')}>⬅️ Back</button>
95100
</row>
@@ -101,7 +106,8 @@ const HelpApp = () => {
101106
return (
102107
<>
103108
<b>Bot Features</b>
104-
{'\n\n'}
109+
<br />
110+
<br />
105111
<blockquote expandable>
106112
This bot demonstrates a React-based Telegram bot using a custom reconciler.
107113

@@ -112,7 +118,7 @@ const HelpApp = () => {
112118
• Custom emoji support
113119
• Dynamic content updates
114120
</blockquote>
115-
{'\n'}
121+
<br />
116122
Links: <a href="https://github.com">GitHub</a> | <a href="tg://user?id=123456">Contact</a>
117123
{'\n\n'}
118124
<row>
@@ -125,17 +131,20 @@ const HelpApp = () => {
125131
return (
126132
<>
127133
<b>🤖 React Telegram Bot</b>
128-
{'\n\n'}
134+
<br />
135+
<br />
129136
Welcome! This bot is powered by React ⚛️
130-
{'\n\n'}
137+
<br />
138+
<br />
131139
Available commands:
132-
{'\n'}
140+
<br />
133141
/counter - Interactive counter
134-
{'\n'}
142+
<br />
135143
/todo - Todo list manager
136-
{'\n'}
144+
<br />
137145
/help - This help message
138-
{'\n\n'}
146+
<br />
147+
<br />
139148
<row>
140149
<button onClick={() => setSection('formatting')}>📝 Formatting</button>
141150
<button onClick={() => setSection('features')}>✨ Features</button>

src/example.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const App = () => {
1414
return (
1515
<>
1616
<b>Welcome to Telegram React!</b>
17+
<br />
1718
<i>Current count: {count}</i>
1819
<row>
1920
<button onClick={() => setCount(p => p - 1)}>➖ Decrease</button>

src/examples/input-autodelete-demo.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,38 +22,38 @@ const AutoDeleteDemo: React.FC = () => {
2222
return (
2323
<>
2424
<b>Input Auto-Delete Demo</b>
25-
{'\n\n'}
26-
25+
<br /><br />
2726
Current mode: <b>{mode === 'normal' ? '📝 Normal Mode' : '🤫 Secret Mode'}</b>
28-
{'\n\n'}
27+
<br /><br />
2928

3029
{mode === 'normal' ? (
3130
<>
3231
<i>Send any message - it will stay in the chat.</i>
33-
{'\n'}
32+
<br />
3433
<input onSubmit={handleNormalInput} />
3534
</>
3635
) : (
3736
<>
3837
<i>Send a secret message - it will be deleted automatically!</i>
39-
{'\n'}
38+
<br />
4039
<input onSubmit={handleSecretInput} autoDelete />
4140
</>
4241
)}
4342

44-
{'\n\n'}
43+
<br />
44+
<br />
4545

4646
{messages.length > 0 && (
4747
<>
4848
<b>Received Messages:</b>
49-
{'\n'}
49+
<br />
5050
{messages.map((msg, idx) => (
5151
<React.Fragment key={idx}>
5252
{msg}
53-
{'\n'}
53+
<br />
5454
</React.Fragment>
5555
))}
56-
{'\n'}
56+
<br />
5757
</>
5858
)}
5959

src/examples/quiz-bot.tsx

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,19 @@ const QuizBot: React.FC = () => {
5151
return (
5252
<>
5353
<b>🎉 Quiz Complete!</b>
54-
{'\n\n'}
54+
<br />
55+
<br />
5556
Your final score: <b>{score}/{questions.length}</b>
56-
{'\n\n'}
57+
<br />
58+
<br />
5759
{score === questions.length ?
5860
"Perfect score! Well done! 🌟" :
5961
score >= questions.length / 2 ?
6062
"Good job! 👍" :
6163
"Better luck next time! 📚"
6264
}
63-
{'\n\n'}
65+
<br />
66+
<br />
6467
<row>
6568
<button onClick={restart}>Play Again</button>
6669
</row>
@@ -73,33 +76,36 @@ const QuizBot: React.FC = () => {
7376
return (
7477
<>
7578
<b>Quiz Bot 🤖</b>
76-
{'\n'}
79+
<br />
7780
Question {currentQuestion + 1} of {questions.length}
78-
{'\n'}
81+
<br />
7982
Score: {score}/{currentQuestion}
80-
{'\n\n'}
83+
<br />
84+
<br />
8185

8286
<b>{currentQ?.question}</b>
83-
{'\n\n'}
87+
<br />
88+
<br />
8489

8590
{lastAnswer !== null && (
8691
<>
8792
Your answer: <code>{lastAnswer}</code>
88-
{'\n'}
93+
<br />
8994
{lastAnswer.toLowerCase().trim() === currentQ?.answer ?
9095
"✅ Correct!" :
9196
`❌ Wrong! The answer was: ${currentQ?.answer}`
9297
}
93-
{'\n\n'}
98+
<br />
99+
<br />
94100
{currentQuestion < questions.length - 1 && "Next question coming up..."}
95-
{'\n'}
101+
<br />
96102
</>
97103
)}
98104

99105
{waitingForAnswer && !lastAnswer && (
100106
<>
101107
<i>Reply to this message with your answer!</i>
102-
{'\n'}
108+
<br />
103109
</>
104110
)}
105111

src/input-example.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,31 @@ const InputExample: React.FC = () => {
1919
return (
2020
<>
2121
<b>Input Example</b>
22-
{'\n\n'}
22+
<br />
23+
<br />
2324

2425
{messages.length === 0 ? (
2526
<>
2627
<i>Reply to this message to send text!</i>
27-
{'\n\n'}
28+
<br />
29+
<br />
2830
The bot will echo whatever you type.
2931
</>
3032
) : (
3133
<>
3234
<b>Message History:</b>
33-
{'\n'}
35+
<br />
3436
{messages.map((msg, idx) => (
3537
<React.Fragment key={idx}>
3638
{msg}
37-
{'\n'}
39+
<br />
3840
</React.Fragment>
3941
))}
4042
</>
4143
)}
4244

43-
{'\n\n'}
45+
<br />
46+
<br />
4447

4548
{/* Input handler - will process any reply to this message */}
4649
{waitingForInput && <input onSubmit={handleInput} autoDelete />}

src/jsx.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ declare module 'react' {
6060
onSubmit?: (text: string) => void;
6161
autoDelete?: boolean;
6262
};
63+
64+
// Line break
65+
br: {};
6366
}
6467
}
6568
}

src/reconciler.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ const hostConfig: ReactReconciler.HostConfig<
114114
return { type: 'row', children: [] };
115115
case 'input':
116116
return { type: 'input', onSubmit: props.onSubmit, autoDelete: props.autoDelete };
117+
case 'br':
118+
return { type: 'text', content: '\n' };
117119
default:
118120
return { type: 'formatted', format: 'bold', children: [] };
119121
}

0 commit comments

Comments
 (0)