feat(person): render precise life dates on cards, hover card, and mention dropdown
Cards compose aria-hidden * / † glyphs in markup so screen readers only announce the dates; PersonSummaryDTO list card stays year-shaped by design (ADR-039). MentionDropdown subtitle wraps instead of truncating so DAY-precision ranges fit at 320px. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,8 +14,10 @@ const AUGUSTE: Person = {
|
||||
displayName: 'Auguste Raddatz',
|
||||
personType: 'PERSON',
|
||||
familyMember: true,
|
||||
birthYear: 1882,
|
||||
deathYear: 1944
|
||||
birthDate: '1882-01-01',
|
||||
birthDatePrecision: 'YEAR',
|
||||
deathDate: '1944-01-01',
|
||||
deathDatePrecision: 'YEAR'
|
||||
} as unknown as Person;
|
||||
|
||||
const POSITION = { top: 100, left: 200 };
|
||||
@@ -81,18 +83,76 @@ describe('PersonHoverCard — loaded state', () => {
|
||||
await expect.element(page.getByText('Auguste Raddatz')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders the life-date range when birthYear and deathYear are present', async () => {
|
||||
it('renders the life-date range when birth and death dates are present', async () => {
|
||||
render(PersonHoverCard, {
|
||||
personId: 'p-aug',
|
||||
cardId: 'card-1',
|
||||
position: POSITION,
|
||||
state: { status: 'loaded', person: AUGUSTE, relationships: [] }
|
||||
});
|
||||
await expect.element(page.getByText('* 1882 – † 1944')).toBeInTheDocument();
|
||||
await expect
|
||||
.element(page.getByTestId('person-hover-card-dates'))
|
||||
.toHaveTextContent('* 1882 – † 1944');
|
||||
});
|
||||
|
||||
it('omits the life-date line when both years are missing', async () => {
|
||||
const noDates = { ...AUGUSTE, birthYear: undefined, deathYear: undefined } as Person;
|
||||
it('renders a DAY-precision birth date as a full localized date', async () => {
|
||||
const exact = {
|
||||
...AUGUSTE,
|
||||
birthDate: '1882-03-14',
|
||||
birthDatePrecision: 'DAY'
|
||||
} as unknown as Person;
|
||||
render(PersonHoverCard, {
|
||||
personId: 'p-aug',
|
||||
cardId: 'card-1',
|
||||
position: POSITION,
|
||||
state: { status: 'loaded', person: exact, relationships: [] }
|
||||
});
|
||||
await expect
|
||||
.element(page.getByTestId('person-hover-card-dates'))
|
||||
.toHaveTextContent('14. März 1882');
|
||||
});
|
||||
|
||||
it('renders APPROX-precision legacy dates with the ca. prefix', async () => {
|
||||
const approx = {
|
||||
...AUGUSTE,
|
||||
birthDate: '1882-01-01',
|
||||
birthDatePrecision: 'APPROX',
|
||||
deathDate: undefined,
|
||||
deathDatePrecision: 'UNKNOWN'
|
||||
} as unknown as Person;
|
||||
render(PersonHoverCard, {
|
||||
personId: 'p-aug',
|
||||
cardId: 'card-1',
|
||||
position: POSITION,
|
||||
state: { status: 'loaded', person: approx, relationships: [] }
|
||||
});
|
||||
await expect.element(page.getByTestId('person-hover-card-dates')).toHaveTextContent('ca. 1882');
|
||||
});
|
||||
|
||||
it('keeps the * and † glyphs out of the accessible text via aria-hidden', async () => {
|
||||
render(PersonHoverCard, {
|
||||
personId: 'p-aug',
|
||||
cardId: 'card-1',
|
||||
position: POSITION,
|
||||
state: { status: 'loaded', person: AUGUSTE, relationships: [] }
|
||||
});
|
||||
const hidden = [
|
||||
...document.querySelectorAll(
|
||||
'[data-testid="person-hover-card-dates"] span[aria-hidden="true"]'
|
||||
)
|
||||
].map((el) => el.textContent?.trim());
|
||||
expect(hidden).toContain('*');
|
||||
expect(hidden).toContain('†');
|
||||
});
|
||||
|
||||
it('omits the life-date line when both dates are missing', async () => {
|
||||
const noDates = {
|
||||
...AUGUSTE,
|
||||
birthDate: undefined,
|
||||
birthDatePrecision: 'UNKNOWN',
|
||||
deathDate: undefined,
|
||||
deathDatePrecision: 'UNKNOWN'
|
||||
} as unknown as Person;
|
||||
render(PersonHoverCard, {
|
||||
personId: 'p-aug',
|
||||
cardId: 'card-1',
|
||||
|
||||
Reference in New Issue
Block a user