Round #156Score 4.5/5Transport: bus

A long-overdue SegmentedControl settled one round after Leaderboard

Route: /bus-ticket
Desktop preview
Mobile preview

Captured at a 375px viewport. Long pages scroll inside the frame.

The screenshots stay in Japanese. Every round is a real screen for a real Japanese industry, so an English re-render would no longer be the screen the agent actually produced.

Write-up

A long-overdue SegmentedControl settled one round after Leaderboard

⁠Build log series⁠: I give an AI that has never seen Gunjo (@gunjo/ui) only the public npm package and the gunjo.jp docs, then ask it to build a real screen. ⁠This fourth passenger-facing bus round⁠ deepened the weaker side with a ⁠mobile ticket, day pass, and IC flow⁠: fare type, adult or child, cash, IC or QR, fare, validity, and presentation while boarding.

Result: 4.5/5, and SegmentedControl settled one round after Leaderboard

The screen passed tsc and fit a 375px mobile-first layout. The agent reported:

⁠The library felt prepared for this screen.⁠ A new adopter building a mobile ticket flow for Japanese transportation reached the right components quickly. The hard parts were all first-class: ticket face, expiry, fare ledger, and bottom dock. The only real gap was SegmentedControl.

The core observation: SegmentedControl had already exceeded three cases

Adult or child and cash, IC, or QR need small equal-width choices. ToggleGroup looked close, but the agent found:

⁠There was no SegmentedControl.⁠ Searching only found SegmentedGaugeCard. ToggleGroup hard-codes w-fit items and centers the group, so every adopter has to add w-full justify-stretch [&>*]:flex-1 for a standard equal-width control. Its shared single and multiple API returns string | string[], forcing a cast. A dedicated single-choice SegmentedControl would return a clean string and add the most value.

The pattern had already been hand-rolled for departures and arrivals in and , refunds versus delay certificates in , and personal versus corporate mode in . It had passed three cases, so I built it:

  • SegmentedControl presents two to four equal-width segments in a recessed track, with a raised active state. It follows the mobile platform pattern and uses role="radiogroup", role="radio", roving tabindex, arrow keys, and a selected state that does not rely on color. onValueChange always receives one string.
  • It differs from general, content-width ToggleGroup, large priced RadioCard, and content-switching Tabs. Its job is a compact equal-width mode or segment selector.
  • I changed the by-use-case catalog from two or three equal-width options using ToggleGroup to two through four using SegmentedControl, and added passenger and payment toggles.

PR#414 passed structural verification, tsc, and the build, then confirmed three radiogroups with three checked states (adult, IC, week) and their data slots in the browser. Issue #409 closed. ⁠This was the seventeenth component produced by the series.⁠

What I took away: candidates beyond three cases tend to release in a run

Leaderboard settled in and SegmentedControl here, two consecutive rounds with a build. After 150 rounds, several candidates had accumulated near or beyond the threshold. Deeper bus coverage landed on those stored cases:

  • A safety console provided the third ranking and produced Leaderboard.
  • A mobile ticket made the long-running equal-width selector explicit and produced SegmentedControl.

A mature foundation means most screens validate existing components. When a screen also hits the next stored case, validation turns into a build. The weaker passenger side contains more of those candidates, which is another reason to keep digging there.

What it flagged

  • TicketStub, ExpiryBadge, RadioCard, AmountBreakdown, and BottomActionBar together covered about 95 percent and felt purpose-built.
  • ✅ After the fix, the catalog had no false leads and correctly identified the missing segmented control as the only gap.
  • 🟡 ValidityTimer for a minute-and-second countdown. ExpiryBadge works by day and cannot represent a two-hour ticket. I opened issue #415 for its short-duration twin.

⁠What I built under src this round: SegmentedControl.⁠ The 4.5/5 triggered the overdue build and corrected the catalog.

📊 Component scoreboard (⁠17 built⁠)

ExpiryBadge / BottomActionBar / Gantt with intraday resolution / Leaderboard / ⁠SegmentedControl⁠, plus earlier components In progress: ComparisonTable, inverted metrics at two of three, ValidityTimer at one of three, and ReferralCard.

📋 Mode progress

  • ✈️ Air ✅ / 🚆 Rail ✅ / 🚕 Taxi ✅
  • 🚌 ⁠Bus: five staff + four passenger screens (arrivals, intercity booking, route search, mobile ticket)⁠, two passenger screens short of comparable depth
  • 🚚 Trucking: not started

Next up: build log

  • Continue passenger bus with IC or commuter passes and service information, or open trucking.

The run

SegmentedControl settled one round after Leaderboard. Deep coverage validates the foundation while releasing candidates that have waited beyond three cases.

This series is co-created with AI (Claude and Codex). A human designs the experiments, makes the calls, and fact-checks before publishing; the AI does the hands-on work and drafting.

Components from @gunjo/ui

The components this screen's source imports directly.

The code the agent actually wrote

Click a file to expand its source.

業界別「AI指示書パック」、先行登録を受付中です。