baraqex 1.0.32 → 1.0.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/baraqex.js +28 -27
- package/dist/server/index.d.ts +3 -6
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +8 -125
- package/dist/server/index.js.map +1 -1
- package/package.json +8 -2
- package/templates/fullstack-app/src/pages/index.js +0 -0
- package/templates/fullstack-template/src/pages/index.js +193 -48
- package/templates/ssr-template/package-lock.json +5080 -0
- package/templates/ssr-template/package.json +8 -14
- package/templates/ssr-template/src/App.tsx +7 -19
- package/templates/ssr-template/src/client.tsx +1 -21
- package/templates/ssr-template/src/server.ts +14 -183
- package/templates/ssr-template/tsconfig.json +6 -15
- package/templates/ssr-template/tsconfig.server.json +5 -18
- package/templates/ssr-template/vite.config.ts +0 -0
- package/templates/wasm/build-wasm.js +228 -0
- package/templates/wasm/esbuild.config.js +63 -0
- package/templates/wasm/go/main.go +256 -0
- package/templates/wasm/go/wasm_exec.js +0 -0
- package/templates/wasm/index.html +97 -0
- package/templates/wasm/jsx-shim.js +9 -0
- package/templates/wasm/package-lock.json +4848 -0
- package/templates/wasm/package.json +27 -0
- package/templates/wasm/public/example.wasm +0 -0
- package/templates/wasm/public/wasm_exec.js +572 -0
- package/templates/wasm/src/App.tsx +519 -0
- package/templates/wasm/src/client.tsx +220 -0
- package/templates/wasm/src/index.html +14 -0
- package/templates/wasm/src/index.tsx +21 -0
- package/templates/wasm/src/main.tsx +5 -0
- package/templates/wasm/src/server.ts +145 -0
- package/templates/wasm/src/wasm-loader.ts +119 -0
- package/templates/wasm/tsconfig.json +21 -0
- package/templates/wasm/tsconfig.node.json +13 -0
- package/templates/wasm/tsconfig.server.json +23 -0
- package/templates/wasm/vite.config.ts +73 -0
- package/templates/wasm/wasm-loader.js +103 -0
|
@@ -0,0 +1,519 @@
|
|
|
1
|
+
import { jsx, useState, useEffect } from 'frontend-hamroun';
|
|
2
|
+
import { loadGoWasm, callWasmFunction, isWasmReady, getWasmError } from './wasm-loader';
|
|
3
|
+
|
|
4
|
+
export default function App() {
|
|
5
|
+
const [wasmReady, setWasmReady] = useState(false);
|
|
6
|
+
const [wasmError, setWasmError] = useState<string | null>(null);
|
|
7
|
+
const [result, setResult] = useState<any>(null);
|
|
8
|
+
const [inputA, setInputA] = useState(10);
|
|
9
|
+
const [inputB, setInputB] = useState(20);
|
|
10
|
+
const [fibInput, setFibInput] = useState(10);
|
|
11
|
+
const [primeInput, setPrimeInput] = useState(17);
|
|
12
|
+
const [name, setName] = useState('World');
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
let mounted = true;
|
|
16
|
+
|
|
17
|
+
async function loadWasm() {
|
|
18
|
+
try {
|
|
19
|
+
console.log('Loading Go WASM module...');
|
|
20
|
+
|
|
21
|
+
// Load WASM using local loader
|
|
22
|
+
await loadGoWasm('/example.wasm', {
|
|
23
|
+
debug: true,
|
|
24
|
+
onLoad: () => {
|
|
25
|
+
console.log('WASM module loaded successfully');
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
if (mounted) {
|
|
30
|
+
setWasmReady(true);
|
|
31
|
+
setWasmError(null);
|
|
32
|
+
console.log('WASM module ready');
|
|
33
|
+
}
|
|
34
|
+
} catch (error) {
|
|
35
|
+
console.error('WASM loading error:', error);
|
|
36
|
+
if (mounted) {
|
|
37
|
+
setWasmError(error instanceof Error ? error.message : 'Unknown WASM loading error');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
loadWasm();
|
|
43
|
+
|
|
44
|
+
return () => {
|
|
45
|
+
mounted = false;
|
|
46
|
+
};
|
|
47
|
+
}, []);
|
|
48
|
+
|
|
49
|
+
// Call WASM functions with error handling
|
|
50
|
+
const callFunction = (funcName: string, ...args: any[]) => {
|
|
51
|
+
try {
|
|
52
|
+
if (!isWasmReady()) {
|
|
53
|
+
throw new Error('WASM not ready yet');
|
|
54
|
+
}
|
|
55
|
+
return callWasmFunction(funcName, ...args);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
const errorMsg = error instanceof Error ? error.message : 'Function call failed';
|
|
58
|
+
setWasmError(errorMsg);
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const handleHello = () => {
|
|
64
|
+
const greeting = callFunction('goHello', name);
|
|
65
|
+
if (greeting !== null) {
|
|
66
|
+
setResult({ type: 'hello', value: greeting, input: name });
|
|
67
|
+
setWasmError(null);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const handleAddition = () => {
|
|
72
|
+
const sum = callFunction('goAdd', inputA, inputB);
|
|
73
|
+
if (sum !== null) {
|
|
74
|
+
setResult({ type: 'addition', value: sum, inputs: [inputA, inputB] });
|
|
75
|
+
setWasmError(null);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const handleMultiplication = () => {
|
|
80
|
+
const product = callFunction('goMultiply', inputA, inputB);
|
|
81
|
+
if (product !== null) {
|
|
82
|
+
setResult({ type: 'multiplication', value: product, inputs: [inputA, inputB] });
|
|
83
|
+
setWasmError(null);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const handleFibonacci = () => {
|
|
88
|
+
if (fibInput > 40) {
|
|
89
|
+
setWasmError('Fibonacci input too large (max 40)');
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const fibResult = callFunction('goFibonacci', fibInput);
|
|
93
|
+
if (fibResult !== null) {
|
|
94
|
+
setResult({ type: 'fibonacci', value: fibResult, input: fibInput });
|
|
95
|
+
setWasmError(null);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const handlePrimeCheck = () => {
|
|
100
|
+
const isPrime = callFunction('goIsPrime', primeInput);
|
|
101
|
+
if (isPrime !== null) {
|
|
102
|
+
setResult({ type: 'prime', value: isPrime, input: primeInput });
|
|
103
|
+
setWasmError(null);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// Get current error (either from state or WASM loader)
|
|
108
|
+
const currentError = wasmError || getWasmError();
|
|
109
|
+
|
|
110
|
+
if (!wasmReady && !currentError) {
|
|
111
|
+
return (
|
|
112
|
+
<div className="app loading">
|
|
113
|
+
<div className="spinner"></div>
|
|
114
|
+
<h2>Loading Go WASM Module...</h2>
|
|
115
|
+
<p>Initializing WebAssembly runtime...</p>
|
|
116
|
+
</div>
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (currentError) {
|
|
121
|
+
return (
|
|
122
|
+
<div className="app error">
|
|
123
|
+
<h2>WASM Error</h2>
|
|
124
|
+
<p>{currentError}</p>
|
|
125
|
+
<button onClick={() => window.location.reload()}>Reload Page</button>
|
|
126
|
+
<details style={{ marginTop: '20px', textAlign: 'left' }}>
|
|
127
|
+
<summary>Troubleshooting</summary>
|
|
128
|
+
<ul>
|
|
129
|
+
<li>Make sure the WASM file is built: <code>npm run build:wasm</code></li>
|
|
130
|
+
<li>Check if <code>example.wasm</code> exists in the public folder</li>
|
|
131
|
+
<li>Verify <code>wasm_exec.js</code> is loaded in the HTML</li>
|
|
132
|
+
<li>Check browser console for additional errors</li>
|
|
133
|
+
</ul>
|
|
134
|
+
</details>
|
|
135
|
+
</div>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return (
|
|
140
|
+
<div className="app">
|
|
141
|
+
<header>
|
|
142
|
+
<h1>Baraqex + Go WASM Template</h1>
|
|
143
|
+
<p>High-performance computing with WebAssembly</p>
|
|
144
|
+
<div className="status">
|
|
145
|
+
<span className="status-indicator ready"></span>
|
|
146
|
+
WASM Ready
|
|
147
|
+
</div>
|
|
148
|
+
</header>
|
|
149
|
+
|
|
150
|
+
<main>
|
|
151
|
+
<section className="demo-grid">
|
|
152
|
+
{/* Hello Function */}
|
|
153
|
+
<div className="demo-card">
|
|
154
|
+
<h3>🌍 Hello Function</h3>
|
|
155
|
+
<div className="input-group">
|
|
156
|
+
<input
|
|
157
|
+
type="text"
|
|
158
|
+
value={name}
|
|
159
|
+
onChange={(e) => setName(e.target.value)}
|
|
160
|
+
placeholder="Enter your name"
|
|
161
|
+
/>
|
|
162
|
+
<button onClick={handleHello}>Say Hello</button>
|
|
163
|
+
</div>
|
|
164
|
+
<small>callWasmFunction('goHello', '{name}')</small>
|
|
165
|
+
</div>
|
|
166
|
+
|
|
167
|
+
{/* Math Operations */}
|
|
168
|
+
<div className="demo-card">
|
|
169
|
+
<h3>🧮 Math Operations</h3>
|
|
170
|
+
<div className="input-group">
|
|
171
|
+
<input
|
|
172
|
+
type="number"
|
|
173
|
+
value={inputA}
|
|
174
|
+
onChange={(e) => setInputA(Number(e.target.value))}
|
|
175
|
+
placeholder="First number"
|
|
176
|
+
/>
|
|
177
|
+
<input
|
|
178
|
+
type="number"
|
|
179
|
+
value={inputB}
|
|
180
|
+
onChange={(e) => setInputB(Number(e.target.value))}
|
|
181
|
+
placeholder="Second number"
|
|
182
|
+
/>
|
|
183
|
+
</div>
|
|
184
|
+
<div className="button-group">
|
|
185
|
+
<button onClick={handleAddition}>Add</button>
|
|
186
|
+
<button onClick={handleMultiplication}>Multiply</button>
|
|
187
|
+
</div>
|
|
188
|
+
<small>Go functions: goAdd, goMultiply</small>
|
|
189
|
+
</div>
|
|
190
|
+
|
|
191
|
+
{/* Fibonacci */}
|
|
192
|
+
<div className="demo-card">
|
|
193
|
+
<h3>🔢 Fibonacci Sequence</h3>
|
|
194
|
+
<div className="input-group">
|
|
195
|
+
<input
|
|
196
|
+
type="number"
|
|
197
|
+
value={fibInput}
|
|
198
|
+
onChange={(e) => setFibInput(Number(e.target.value))}
|
|
199
|
+
placeholder="Fibonacci number"
|
|
200
|
+
min="0"
|
|
201
|
+
max="40"
|
|
202
|
+
/>
|
|
203
|
+
<button onClick={handleFibonacci}>Calculate</button>
|
|
204
|
+
</div>
|
|
205
|
+
<small>Maximum value: 40</small>
|
|
206
|
+
</div>
|
|
207
|
+
|
|
208
|
+
{/* Prime Check */}
|
|
209
|
+
<div className="demo-card">
|
|
210
|
+
<h3>🔍 Prime Number Check</h3>
|
|
211
|
+
<div className="input-group">
|
|
212
|
+
<input
|
|
213
|
+
type="number"
|
|
214
|
+
value={primeInput}
|
|
215
|
+
onChange={(e) => setPrimeInput(Number(e.target.value))}
|
|
216
|
+
placeholder="Number to check"
|
|
217
|
+
min="1"
|
|
218
|
+
/>
|
|
219
|
+
<button onClick={handlePrimeCheck}>Check Prime</button>
|
|
220
|
+
</div>
|
|
221
|
+
</div>
|
|
222
|
+
</section>
|
|
223
|
+
|
|
224
|
+
{/* Results Display */}
|
|
225
|
+
{result && (
|
|
226
|
+
<section className="results">
|
|
227
|
+
<h2>📊 WASM Result</h2>
|
|
228
|
+
<div className="result-card">
|
|
229
|
+
{result.type === 'hello' && (
|
|
230
|
+
<p><strong>Greeting:</strong> <span className="result-value">{result.value}</span></p>
|
|
231
|
+
)}
|
|
232
|
+
{result.type === 'addition' && (
|
|
233
|
+
<p><strong>Addition:</strong> {result.inputs[0]} + {result.inputs[1]} = <span className="result-value">{result.value}</span></p>
|
|
234
|
+
)}
|
|
235
|
+
{result.type === 'multiplication' && (
|
|
236
|
+
<p><strong>Multiplication:</strong> {result.inputs[0]} × {result.inputs[1]} = <span className="result-value">{result.value}</span></p>
|
|
237
|
+
)}
|
|
238
|
+
{result.type === 'fibonacci' && (
|
|
239
|
+
<p><strong>Fibonacci:</strong> F({result.input}) = <span className="result-value">{result.value}</span></p>
|
|
240
|
+
)}
|
|
241
|
+
{result.type === 'prime' && (
|
|
242
|
+
<p><strong>Prime Check:</strong> {result.input} is <span className="result-value">{result.value ? 'prime' : 'not prime'}</span></p>
|
|
243
|
+
)}
|
|
244
|
+
</div>
|
|
245
|
+
</section>
|
|
246
|
+
)}
|
|
247
|
+
|
|
248
|
+
{/* Info Section */}
|
|
249
|
+
<section className="info-section">
|
|
250
|
+
<h2>⚡ Baraqex WASM Benefits</h2>
|
|
251
|
+
<div className="benefits-grid">
|
|
252
|
+
<div className="benefit">
|
|
253
|
+
<h4>🚀 Simple API</h4>
|
|
254
|
+
<p>Easy-to-use loadGoWasm() and callWasmFunction() API</p>
|
|
255
|
+
</div>
|
|
256
|
+
<div className="benefit">
|
|
257
|
+
<h4>🔄 Cross-Platform</h4>
|
|
258
|
+
<p>Works in browser and Node.js with same API</p>
|
|
259
|
+
</div>
|
|
260
|
+
<div className="benefit">
|
|
261
|
+
<h4>🛠️ Go Integration</h4>
|
|
262
|
+
<p>Seamless Go + JavaScript interoperability</p>
|
|
263
|
+
</div>
|
|
264
|
+
<div className="benefit">
|
|
265
|
+
<h4>📊 Debug Support</h4>
|
|
266
|
+
<p>Built-in debugging and function discovery</p>
|
|
267
|
+
</div>
|
|
268
|
+
</div>
|
|
269
|
+
</section>
|
|
270
|
+
</main>
|
|
271
|
+
|
|
272
|
+
<style>{`
|
|
273
|
+
.app {
|
|
274
|
+
max-width: 1200px;
|
|
275
|
+
margin: 0 auto;
|
|
276
|
+
padding: 20px;
|
|
277
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
278
|
+
line-height: 1.6;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.app.loading, .app.error {
|
|
282
|
+
text-align: center;
|
|
283
|
+
padding: 60px 20px;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.spinner {
|
|
287
|
+
width: 50px;
|
|
288
|
+
height: 50px;
|
|
289
|
+
border: 4px solid #f3f3f3;
|
|
290
|
+
border-top: 4px solid #007acc;
|
|
291
|
+
border-radius: 50%;
|
|
292
|
+
animation: spin 1s linear infinite;
|
|
293
|
+
margin: 0 auto 20px;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
@keyframes spin {
|
|
297
|
+
0% { transform: rotate(0deg); }
|
|
298
|
+
100% { transform: rotate(360deg); }
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
header {
|
|
302
|
+
text-align: center;
|
|
303
|
+
margin-bottom: 40px;
|
|
304
|
+
padding: 30px;
|
|
305
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
306
|
+
color: white;
|
|
307
|
+
border-radius: 16px;
|
|
308
|
+
position: relative;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
header h1 {
|
|
312
|
+
margin: 0 0 10px 0;
|
|
313
|
+
font-size: 2.5rem;
|
|
314
|
+
font-weight: 700;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
header p {
|
|
318
|
+
margin: 0 0 20px 0;
|
|
319
|
+
opacity: 0.9;
|
|
320
|
+
font-size: 1.1rem;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
.status {
|
|
324
|
+
display: inline-flex;
|
|
325
|
+
align-items: center;
|
|
326
|
+
gap: 8px;
|
|
327
|
+
background: rgba(255, 255, 255, 0.2);
|
|
328
|
+
padding: 8px 16px;
|
|
329
|
+
border-radius: 20px;
|
|
330
|
+
font-size: 0.9rem;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.status-indicator {
|
|
334
|
+
width: 8px;
|
|
335
|
+
height: 8px;
|
|
336
|
+
border-radius: 50%;
|
|
337
|
+
background: #4ade80;
|
|
338
|
+
animation: pulse 2s infinite;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
@keyframes pulse {
|
|
342
|
+
0%, 100% { opacity: 1; }
|
|
343
|
+
50% { opacity: 0.5; }
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
.demo-grid {
|
|
347
|
+
display: grid;
|
|
348
|
+
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
349
|
+
gap: 20px;
|
|
350
|
+
margin-bottom: 30px;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.demo-card {
|
|
354
|
+
background: white;
|
|
355
|
+
padding: 24px;
|
|
356
|
+
border-radius: 12px;
|
|
357
|
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
358
|
+
border: 1px solid #e5e7eb;
|
|
359
|
+
transition: transform 0.2s, box-shadow 0.2s;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
.demo-card:hover {
|
|
363
|
+
transform: translateY(-2px);
|
|
364
|
+
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
.demo-card h3 {
|
|
368
|
+
margin-top: 0;
|
|
369
|
+
margin-bottom: 16px;
|
|
370
|
+
color: #374151;
|
|
371
|
+
font-size: 1.2rem;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
.input-group {
|
|
375
|
+
display: flex;
|
|
376
|
+
gap: 8px;
|
|
377
|
+
margin-bottom: 12px;
|
|
378
|
+
flex-wrap: wrap;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.button-group {
|
|
382
|
+
display: flex;
|
|
383
|
+
gap: 8px;
|
|
384
|
+
flex-wrap: wrap;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
input {
|
|
388
|
+
flex: 1;
|
|
389
|
+
min-width: 120px;
|
|
390
|
+
padding: 10px 12px;
|
|
391
|
+
border: 2px solid #e5e7eb;
|
|
392
|
+
border-radius: 8px;
|
|
393
|
+
font-size: 14px;
|
|
394
|
+
transition: border-color 0.2s;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
input:focus {
|
|
398
|
+
outline: none;
|
|
399
|
+
border-color: #007acc;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
button {
|
|
403
|
+
background: #007acc;
|
|
404
|
+
color: white;
|
|
405
|
+
border: none;
|
|
406
|
+
padding: 10px 16px;
|
|
407
|
+
border-radius: 8px;
|
|
408
|
+
cursor: pointer;
|
|
409
|
+
font-size: 14px;
|
|
410
|
+
font-weight: 600;
|
|
411
|
+
transition: all 0.2s;
|
|
412
|
+
white-space: nowrap;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
button:hover {
|
|
416
|
+
background: #0056a3;
|
|
417
|
+
transform: translateY(-1px);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
button:active {
|
|
421
|
+
transform: translateY(0);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
small {
|
|
425
|
+
color: #6b7280;
|
|
426
|
+
font-size: 0.8rem;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
.results {
|
|
430
|
+
background: #f0f9ff;
|
|
431
|
+
padding: 24px;
|
|
432
|
+
border-radius: 12px;
|
|
433
|
+
border: 2px solid #bae6fd;
|
|
434
|
+
margin: 30px 0;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
.results h2 {
|
|
438
|
+
margin-top: 0;
|
|
439
|
+
color: #0369a1;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
.result-card {
|
|
443
|
+
background: white;
|
|
444
|
+
padding: 16px;
|
|
445
|
+
border-radius: 8px;
|
|
446
|
+
border: 1px solid #bae6fd;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
.result-value {
|
|
450
|
+
font-weight: bold;
|
|
451
|
+
color: #007acc;
|
|
452
|
+
background: #e0f2fe;
|
|
453
|
+
padding: 2px 6px;
|
|
454
|
+
border-radius: 4px;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
.error {
|
|
458
|
+
color: #dc2626;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
.error button {
|
|
462
|
+
background: #dc2626;
|
|
463
|
+
margin-top: 20px;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
.error button:hover {
|
|
467
|
+
background: #b91c1c;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
details {
|
|
471
|
+
background: #fef2f2;
|
|
472
|
+
padding: 16px;
|
|
473
|
+
border-radius: 8px;
|
|
474
|
+
border: 1px solid #fecaca;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
summary {
|
|
478
|
+
cursor: pointer;
|
|
479
|
+
font-weight: 600;
|
|
480
|
+
margin-bottom: 8px;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
code {
|
|
484
|
+
background: #f3f4f6;
|
|
485
|
+
padding: 2px 4px;
|
|
486
|
+
border-radius: 4px;
|
|
487
|
+
font-family: monospace;
|
|
488
|
+
font-size: 0.9em;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
@media (max-width: 768px) {
|
|
492
|
+
.app {
|
|
493
|
+
padding: 10px;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
header {
|
|
497
|
+
padding: 20px;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
header h1 {
|
|
501
|
+
font-size: 2rem;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
.demo-grid {
|
|
505
|
+
grid-template-columns: 1fr;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
.input-group {
|
|
509
|
+
flex-direction: column;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
input {
|
|
513
|
+
min-width: auto;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
`}</style>
|
|
517
|
+
</div>
|
|
518
|
+
);
|
|
519
|
+
}
|