@maiyunnet/kebab 9.14.2 → 9.15.0

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.
@@ -59,7 +59,7 @@ interface IProps {
59
59
  // ─── 页面内部组件(仅本页演示使用,无需提取到 lib/)────────────────────────────
60
60
 
61
61
  /** --- 卡片容器 --- */
62
- function Card({ children, className = '' }: { 'children': ReactNode; 'className'?: string }) {
62
+ function Card({ children, className = '' }: { 'children': ReactNode; 'className'?: string; }) {
63
63
  return (
64
64
  <div className={`bg-white rounded-xl shadow-sm border border-slate-200 p-6 ${className}`}>
65
65
  {children}
@@ -75,7 +75,7 @@ function Badge({ children, variant = 'default' }: {
75
75
  const styles = {
76
76
  'default': 'bg-blue-100 text-blue-700',
77
77
  'success': 'bg-green-100 text-green-700',
78
- 'warn': 'bg-amber-100 text-amber-700',
78
+ 'warn': 'bg-amber-100 text-amber-700',
79
79
  };
80
80
  return (
81
81
  <span className={`inline-flex px-2.5 py-0.5 rounded-md text-xs font-semibold ${styles[variant]}`}>
@@ -137,13 +137,13 @@ function RouterAbout() {
137
137
  <p className="text-slate-500 text-xs mb-3">useNavigate() programmatic navigation (without Link component):</p>
138
138
  <div className="flex gap-2">
139
139
  <button
140
- onClick={() => navigate('/')}
140
+ onClick={() => { Promise.resolve(navigate('/')).catch(() => {}); }}
141
141
  className="inline-flex items-center px-3 py-1.5 rounded-lg border border-slate-300 hover:bg-slate-50 text-slate-700 text-xs font-medium cursor-pointer"
142
142
  >
143
143
  ← Back to /
144
144
  </button>
145
145
  <button
146
- onClick={() => navigate('/user/99')}
146
+ onClick={() => { Promise.resolve(navigate('/user/99')).catch(() => {}); }}
147
147
  className="inline-flex items-center px-3 py-1.5 rounded-lg bg-blue-500 hover:bg-blue-600 text-white text-xs font-medium cursor-pointer"
148
148
  >
149
149
  → /user/99
@@ -155,7 +155,7 @@ function RouterAbout() {
155
155
 
156
156
  /** --- 路由 User 动态参数页 --- */
157
157
  function RouterUser() {
158
- const { id } = useParams<{ 'id': string }>();
158
+ const { id } = useParams<{ 'id': string; }>();
159
159
  const navigate = useNavigate();
160
160
  return (
161
161
  <div>
@@ -166,7 +166,7 @@ function RouterUser() {
166
166
  useParams() dynamic segment: <code className="bg-slate-100 px-1 rounded">id = &quot;{id}&quot;</code>
167
167
  </p>
168
168
  <button
169
- onClick={() => navigate('/')}
169
+ onClick={() => { Promise.resolve(navigate('/')).catch(() => {}); }}
170
170
  className="inline-flex items-center px-3 py-1.5 rounded-lg border border-slate-300 hover:bg-slate-50 text-slate-700 text-xs font-medium cursor-pointer"
171
171
  >
172
172
  ← Back to /
@@ -195,7 +195,7 @@ function ShadcnDemo() {
195
195
  const agreeId = useId();
196
196
  const newsletterId = useId();
197
197
 
198
- function handleSubmit(e: React.FormEvent<HTMLFormElement>): void {
198
+ function handleSubmit(e: React.SyntheticEvent<HTMLFormElement>): void {
199
199
  e.preventDefault();
200
200
  setSubmitted(true);
201
201
  }
@@ -226,7 +226,7 @@ function ShadcnDemo() {
226
226
  type="text"
227
227
  placeholder="Enter your username"
228
228
  value={name}
229
- onChange={e => setName(e.target.value)}
229
+ onChange={e => { setName(e.target.value); }}
230
230
  />
231
231
  </div>
232
232
  <div className="grid gap-1.5">
@@ -236,7 +236,7 @@ function ShadcnDemo() {
236
236
  type="email"
237
237
  placeholder="you@example.com"
238
238
  value={email}
239
- onChange={e => setEmail(e.target.value)}
239
+ onChange={e => { setEmail(e.target.value); }}
240
240
  />
241
241
  </div>
242
242
  </div>
@@ -290,7 +290,7 @@ function ShadcnDemo() {
290
290
  2
291
291
  )}</pre>
292
292
  <button
293
- onClick={() => setSubmitted(false)}
293
+ onClick={() => { setSubmitted(false); }}
294
294
  className="text-xs text-blue-500 hover:underline cursor-pointer"
295
295
  >Reset</button>
296
296
  </div>
@@ -303,7 +303,7 @@ function ShadcnDemo() {
303
303
  required
304
304
  placeholder="At least 2 characters"
305
305
  value={name}
306
- onChange={e => setName(e.target.value)}
306
+ onChange={e => { setName(e.target.value); }}
307
307
  />
308
308
  </div>
309
309
  <div className="grid gap-1.5">
@@ -314,7 +314,7 @@ function ShadcnDemo() {
314
314
  required
315
315
  placeholder="you@example.com"
316
316
  value={email}
317
- onChange={e => setEmail(e.target.value)}
317
+ onChange={e => { setEmail(e.target.value); }}
318
318
  />
319
319
  </div>
320
320
  <div className="flex items-center gap-2">
@@ -417,7 +417,7 @@ export default function ReactPage({ title, serverTime, node, _urlBase, _urlStc,
417
417
  {(['overview', 'routing', 'fetch', 'shadcn'] as const).map(t => (
418
418
  <button
419
419
  key={t}
420
- onClick={() => setTab(t)}
420
+ onClick={() => { setTab(t); }}
421
421
  className={[
422
422
  'px-4 py-2 rounded-md text-sm font-medium transition-colors cursor-pointer',
423
423
  tab === t ? 'bg-white shadow text-slate-900' : 'text-slate-500 hover:text-slate-900',
@@ -441,12 +441,12 @@ export default function ReactPage({ title, serverTime, node, _urlBase, _urlStc,
441
441
  </p>
442
442
  <div className="flex items-center gap-4">
443
443
  <button
444
- onClick={() => setCount(c => c - 1)}
444
+ onClick={() => { setCount(c => c - 1); }}
445
445
  className="w-10 h-10 rounded-lg border border-slate-300 hover:bg-slate-50 font-bold text-slate-700 text-xl cursor-pointer"
446
446
  >−</button>
447
447
  <span className="text-3xl font-bold text-slate-900 w-10 text-center tabular-nums">{count}</span>
448
448
  <button
449
- onClick={() => setCount(c => c + 1)}
449
+ onClick={() => { setCount(c => c + 1); }}
450
450
  className="w-10 h-10 rounded-lg bg-blue-500 hover:bg-blue-600 text-white font-bold text-xl cursor-pointer"
451
451
  >+</button>
452
452
  </div>
@@ -459,7 +459,8 @@ export default function ReactPage({ title, serverTime, node, _urlBase, _urlStc,
459
459
  Passed via{' '}
460
460
  <code className="bg-slate-100 px-1 rounded">_loadReactPage(path, props)</code>.
461
461
  The framework auto-injects constants like _urlBase and serializes
462
- all props as inline JSON, reused directly during client hydration — no extra request needed.
462
+ all props as inline JSON, reused directly during client hydration —
463
+ no extra request needed.
463
464
  </p>
464
465
  <div className="space-y-2">
465
466
  {([
@@ -491,8 +492,10 @@ export default function ReactPage({ title, serverTime, node, _urlBase, _urlStc,
491
492
  react-page.tsx # Page component (import + compose)`}
492
493
  </pre>
493
494
  <p className="text-slate-500 text-xs mt-3">
494
- Mirrors the shadcn/ui <code className="bg-slate-100 px-1 rounded">components/ui/</code> convention.
495
- In dev mode, the framework auto-scans imports — no manual import map configuration needed.
495
+ Mirrors the shadcn/ui{' '}
496
+ <code className="bg-slate-100 px-1 rounded">components/ui/</code> convention.
497
+ In dev mode, the framework auto-scans imports —
498
+ no manual import map configuration needed.
496
499
  </p>
497
500
  </Card>
498
501
 
@@ -527,7 +530,8 @@ export default function ReactPage({ title, serverTime, node, _urlBase, _urlStc,
527
530
  <h2 className="font-semibold text-slate-900 mb-2">Full-Page BrowserRouter Setup</h2>
528
531
  <p className="text-slate-500 text-xs mb-3">
529
532
  To let React Router manage the real URL (e.g. /app, /app/about),
530
- replace MemoryRouter with BrowserRouter and route all sub-paths to the same Ctr method on the server:
533
+ replace MemoryRouter with BrowserRouter and route all sub-paths
534
+ to the same Ctr method on the server:
531
535
  </p>
532
536
  <pre className="bg-slate-50 border border-slate-200 rounded-lg p-4 text-xs overflow-auto leading-relaxed text-slate-700">{`// 1. route.json: 将所有子路径路由到同一 Ctr 方法
533
537
  {
@@ -561,18 +565,19 @@ await this._loadReactPage('view/my', { ...props }, {
561
565
  <Card>
562
566
  <h2 className="font-semibold text-slate-900 mb-3">Client Fetch Demo</h2>
563
567
  <p className="text-slate-500 text-xs mb-4">
564
- After hydration, click a button to send a GET request. setState triggers a partial re-render — no page refresh.
568
+ After hydration, click a button to send a GET request.
569
+ setState triggers a partial re-render — no page refresh.
565
570
  </p>
566
571
  <div className="flex gap-3 flex-wrap">
567
572
  <Btn
568
- onClick={() => doFetch(`${_urlBase}test/json?type=4`)}
573
+ onClick={() => { doFetch(`${_urlBase}test/json?type=4`); }}
569
574
  disabled={isFetching}
570
575
  >
571
576
  {isFetching ? 'Fetching...' : 'GET /test/json?type=4'}
572
577
  </Btn>
573
578
  <Btn
574
579
  outline
575
- onClick={() => doFetch(`${_urlBase}test/json?type=2`)}
580
+ onClick={() => { doFetch(`${_urlBase}test/json?type=2`); }}
576
581
  disabled={isFetching}
577
582
  >
578
583
  GET type=2 (error resp)