From 93915558594f7d403cf598f03995c55f7996ec2c Mon Sep 17 00:00:00 2001 From: neon <18559658+neonsolstice@users.noreply.github.com> Date: Sun, 30 Aug 2026 17:00:33 +0000 Subject: [PATCH] fix(books): fully expand book synopsis Keep expanded synopsis content in the existing page or column flow so touch users do not encounter an undiscoverable nested scroll area. Expose the toggle state to assistive technology. Fixes #1202 --- .../components/detail/tabs/DetailsTab.vue | 7 +++-- .../detail/tabs/__tests__/DetailsTab.spec.ts | 31 +++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/client/src/features/book/components/detail/tabs/DetailsTab.vue b/client/src/features/book/components/detail/tabs/DetailsTab.vue index 9f0a4cf87..88d90f59d 100644 --- a/client/src/features/book/components/detail/tabs/DetailsTab.vue +++ b/client/src/features/book/components/detail/tabs/DetailsTab.vue @@ -1825,7 +1825,6 @@ watch(
-

@@ -1833,7 +1832,10 @@ watch(

{{ t('book.detail.details.noDescription') }}

diff --git a/client/src/features/book/components/detail/tabs/__tests__/DetailsTab.spec.ts b/client/src/features/book/components/detail/tabs/__tests__/DetailsTab.spec.ts index a81c3a2eb..c8e839d0d 100644 --- a/client/src/features/book/components/detail/tabs/__tests__/DetailsTab.spec.ts +++ b/client/src/features/book/components/detail/tabs/__tests__/DetailsTab.spec.ts @@ -304,6 +304,37 @@ describe('DetailsTab cover surface', () => { expect(wrapper.get('[data-test="hidden-genres"]').text()).toContain('Mystery') }) + it('fully expands the synopsis without creating a nested scroll area', async () => { + const wrapper = mountDetails( + makeBook({ + description: '

First paragraph.

Second paragraph with enough content to continue beyond the collapsed preview.

', + }), + ) + await flushPromises() + + const synopsis = wrapper.get('.line-clamp-4') + expect(synopsis.html()).toContain('Second paragraph') + + const toggle = wrapper.findAll('button').find((button) => button.text() === 'Show more') + expect(toggle).toBeDefined() + expect(toggle!.attributes('aria-controls')).toBe('book-12-synopsis') + expect(toggle!.attributes('aria-expanded')).toBe('false') + expect(synopsis.attributes('id')).toBe('book-12-synopsis') + await toggle!.trigger('click') + + expect(synopsis.classes()).not.toContain('line-clamp-4') + expect(synopsis.classes()).not.toContain('max-h-44') + expect(synopsis.classes()).not.toContain('overflow-y-auto') + expect(toggle!.text()).toBe('Show less') + expect(toggle!.attributes('aria-expanded')).toBe('true') + + await toggle!.trigger('click') + + expect(synopsis.classes()).toContain('line-clamp-4') + expect(toggle!.text()).toBe('Show more') + expect(toggle!.attributes('aria-expanded')).toBe('false') + }) + it('summarizes pending Kobo sync state for each affected device', async () => { mocks.api.mockImplementation(async (input) => { const url = String(input)