Skip to content

0.2.0: the model-year step - #5

Merged
rameerez merged 2 commits into
mainfrom
feat/year-step
Oct 10, 2026
Merged

rameerez merged 2 commits into
mainfrom
feat/year-step

Conversation

@rameerez

Copy link
Copy Markdown
Contributor

An optional third select for the model year, fed by years_on_record on the VehiclesDB model list (shipped on the API side in rameerez/vehiclesdb-web#114).

  • year, placeholderYear, initialYear, yearFallback ("range" default: this year back 40 so a booking form never dead-ends; "none").
  • Years newest first; a saved/initial year outside the span is kept and warned, never dropped; spans outside 1886..next year fall back; host-controlled disabled is respected; includeOther works on the year too.
  • onChange/.value gain year (number | null | "other") only when a year select is attached; without one, behaviour and payloads are byte-identical to 0.1.4 (verified by diffing outputs).
  • 32 tests (27 → 32 after review fixes), README, CHANGELOG, demo.
  • Prose no longer hard-codes the country count.

The website vendors this exact dist (vendor/javascript/make-model-dropdown.js) and its system test drives it against the real API.

Release: npm publish (owner), then bump the CDN pin on vehiclesdb.com/make-and-model-dropdown.

🤖 Generated with Claude Code

rameerez and others added 2 commits October 10, 2026 05:13
Garages put this picker in booking forms, and those forms ask for the
model year; it is the top feature request. The API now carries
`years_on_record` ({first, last} or null) on every model in
GET /makes/{slug}/models, the endpoint the model step already calls, so
the year step needs no request of its own.

- New options: `year` (the third <select>, needs `model`),
  `placeholderYear` ("Year"), `initialYear` (also read from a
  server-rendered selection, reapplied on form reset), `yearFallback`.
- Picking a model fills the years newest first, then announces; a make
  change clears model AND year before announcing. onChange and .value
  gain `year` (number, null, or "other") ONLY when a year select is
  attached, so {make, model} consumers see the exact shape they had.
- The models list is stored with the model select it fills, past the
  stale-response guard, and the year fill reads the model select's
  value at fill time: a late list for an old make can never date the
  new one's models.
- yearFallback "range" (default): a model with no span (about 1 in 8,
  plus "Other / not listed") gets the current year back 40, so the
  field never dead-ends. "none": placeholder only, select disabled
  (the host's own disabled state is restored on re-enable and destroy).
- A missing `years_on_record` key (older API, mocks) or a malformed span
  is treated as null.

Tests: 18 -> 27; the only edit to an existing test is the version
assertion. Demo, README, CHANGELOG, package version updated.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Five review findings against 537c4af, each with a test that fails on it:

- Spans are sane only within 1886 <= first <= last <= next year;
  anything else takes the fallback. {last: 1e300} passed
  Number.isInteger and, as 1e300 - 1 === 1e300, never finished counting
  down; {first: -8000} built 10,028 options; {0, 0} rendered "0";
  {last: 2099} offered 70+ future years. Lists are now capped near 140.
- A host-supplied year (initialYear or a server-rendered selection)
  outside the span is kept: inserted newest-first in its place,
  selected, and announced once via console.warn. Register spans make
  this common in edit forms; it used to come back as year null.
- `disabled` belongs to the host. The widget sets it only for its own
  reason (yearFallback "none" with nothing to choose), remembers that it
  did, and only ever undoes that, on refill and on destroy. initialYear
  no longer skips a host-disabled field.
- yearFallback "none" with includeOther leaves the select enabled with
  placeholder + Other; it is disabled only when there is nothing to pick.
- initialYear now also checks the intended initial make, and tests pin
  both the make and the model checks (each one's removal fails a test).
  The `this.models = null` on make change stays: a test shows it is
  observable when host code injects a model option mid-fetch.

Also: the widget's prose (file header, README, package.json description)
no longer states a register-country count, which had already drifted
(14 -> 15 with Norway); it says "official national vehicle registers".

Tests: 27 -> 32.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@rameerez
rameerez merged commit 605a6a3 into main Oct 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant