---
id: CMI-CRM-ENT-001
title: Address Editor
component: CMP-CRM-ENT-001
product_area: crm
module: entities
revision: 1
status: draft
implementation_evidence: observed
source_sha:
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
repository: react-console
files:
  - components/contact-editor/collections/address-list-editor.tsx
  - components/contact-editor/collections/blank-row.ts
  - components/contact-editor/collections/contact-point-choices.ts
  - components/contact-editor/fields/preferred-star.tsx
  - components/contact-editor/fields/select-field.tsx
  - components/contact-editor/types.ts
  - components/contact-editor/constants.ts
  - components/contact-editor/logic.ts
  - components/forms/contacts/collection-components.tsx
exports:
  - symbol: AddressListEditor
    kind: component
  - symbol: RhythmAddressList
    kind: component
  - symbol: AddressEntry
    kind: type
interfaces:
  - name: AddressListEditorProps
    file: components/contact-editor/collections/address-list-editor.tsx
  - name: AddressEntry
    file: components/contact-editor/types.ts
  - name: RowLinkControls
    file: components/contact-editor/collections/phone-list-editor.tsx
dependencies:
  - on: components/address/address-input.tsx (AddressInput, the Google Places lookup and manual lines)
    why: Provides lookup and manual entry for an expanded address.
  - on: components/affiliations/linked-source.tsx (LinkedSourceMarker)
    why: Presents the source state and its available recovery actions.
  - on: lib/record-pickers/inactive.ts
    why: Formats retained inactive type labels.
  - on: lucide-react
    why: Supplies the decorative action and state icons.
state: Local state tracks expanded cards, the requested focus target and the still-blank first row. The calling form owns committed addresses, validation messages and source decisions.
tests: []
version: react-console baf6dae382d6f41dce976c7f848667ccc37e076f
implementation_state: implemented
conformance: not-verified
fidelity: []
evidence:
  - 'react-console at baf6dae3: the files above; components/contact-editor/__tests__/blank-rows.test.tsx (unit tests of the blank row and the type-on-the-line layout, not yet registered as an executable suite)'
consumers: [SCI-CRM-ENT-002, SCI-CRM-ENT-004]
---

# Address Editor

## What Was Built

The implemented address collection lets a contact form maintain postal details in cards. AddressListEditor renders the cards, and RhythmAddressList adapts it to the compiled form. The shared implementation includes the first blank row, type selection, seasonal controls, an ordinary preferred star and organization source markers. Its source-controlled Remove behavior differs from the draft's earlier description; the finding records that discrepancy.

## Where It Lives

The console stores AddressListEditor and the blank-row and type-choice helpers under the contact editor's collections. Preferred-star and select controls sit in its fields directory. The types, constants and normalization logic belong to the contact editor, while RhythmAddressList lives with the form-engine contact adapters. Shared AddressInput and LinkedSourceMarker supply address entry and source presentation.

## Its Interface

AddressListEditor is an exported component with the local AddressListEditorProps interface. It requires value, onChange and getError; optional props supply types, source controls, lookup preference, geocode display and older work-mirror information. AddressEntry is an exported type, and RowLinkControls is imported from the phone collection. RhythmAddressList is the exported form adapter that binds configured types and source callbacks to the collection. These declarations exist at the pinned commit; the props interface itself is not exported.

## Behavior as Built

The shared blank-row hook holds an empty collection's provisional row locally and commits it under the same key once it becomes nonblank. Add chooses an unused offerable type in a fixed order. Selecting Seasonal clears ordinary preference, and month changes clamp the selected day. Error cards remain expanded. Escape avoids collapsing a card while a relevant popup is open.

Current row link controls suppress direct value editing but do not disable Remove. The older work mirror disables that button. The geocode flag produces a badge rather than coordinates. Autofocus is requested after Add, not for the initial blank card or an ordinary expansion.

## Design Fidelity

The rewritten Component Design describes the observed collection behavior, including the two removal paths, focus limits and geocode badge. The earlier draft described all linked rows as protected from direct removal, initial lookup focus and visible coordinates. FND-CRM-ENT-089 preserves those contradictions for review; this source inspection grants no product approval and leaves conformance not verified.

## Tests

The console's blank-row tests assert an initial address input without Add, omission of blank rows from saving and dirty counts, commitment after editing, and the type selector's placement beside the address control. Inspection of those assertions is evidence of test coverage, not a passing execution in this job. No registered executable suite names these component tests; FND-CRM-ENT-086 records that registration gap, and tests remains empty.

## Who Uses It

Create Contact and Edit Contact consume the address editor through RhythmAddressList when the compiled form includes the Addresses collection. The adapter binds the collection and supplies workspace types and source controls. The corpus's derived consumer list names the registered Edit Contact implementation; this review preserves that list and does not hand-author additional reverse references.
