Skip to content

feat(templates): extract scroll-arrows state into useScrollArrows - #145

Open
moodyjmz wants to merge 2 commits into
mainfrom
feat/scroll-arrows-composable
Open

feat(templates): extract scroll-arrows state into useScrollArrows#145
moodyjmz wants to merge 2 commits into
mainfrom
feat/scroll-arrows-composable

Conversation

@moodyjmz

Copy link
Copy Markdown
Contributor

Summary

PR 1 of #134 — proof of concept for adopting Vue composables as the layer between src/services/ (data) and src/components/ (render): stateful logic with no direct template dependency.

  • Extracts TemplateSection.vue's scroll-arrow state (list ref, canScrollLeft/canScrollRight, updateArrows(), scrollByStep(), the ResizeObserver mount/unmount wiring) into src/composables/useScrollArrows.ts, built on @vueuse/core's useScroll/useResizeObserver rather than hand-rolled — reuse-before-you-write, extended from @nextcloud/* packages to general-purpose Vue utilities.
  • Adds @vueuse/core as a direct dependency (previously only present transitively via @nextcloud/vue; both now resolve to the same 14.3.0, no duplicate copy in the tree).
  • Establishes src/composables/ and its conventions for PR 2 and beyond: return individual refs (not a reactive() object — breaks silently on destructuring), and a shared src/test-utils/withSetup.ts helper for composables that rely on onMounted/onUnmounted (Vue's lifecycle hooks throw outside a real component instance).
  • Closes the a11y gap noted in Adopt Vue composables for stateful non-rendering logic, starting with TemplateSection's scroll-arrows #134 while in this code: the scrollable list now has an aria-label identifying it as a scrollable region, per creator.

Note: #134 cites this gap as issue #59 — that's actually OfficeOverview's favourite-indicator issue, an unrelated a11y gap. Will correct the citation on #134 separately; not blocking this PR.

Reuse before you write

@vueuse/core's useScroll/useResizeObserver — see commit message and #134 for the ladder rationale.

Test plan

  • npm run lint
  • npm run stylelint
  • npm run test:unit (129 passing, includes 8 new composable tests + a new a11y test)
  • npm run build
  • /compile needed once merged-ready — will note in a follow-up comment

Refs #134.

🤖 Generated with Claude Code

moodyjmz and others added 2 commits August 28, 2026 09:17
Already present transitively via @nextcloud/vue, but the app is about
to import from it directly (useScrollArrows), so it needs to be
declared rather than relied on implicitly.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: James Manuel <moodyjmz@users.noreply.github.com>
TemplateSection.vue's list ref, canScrollLeft/canScrollRight,
updateArrows(), scrollByStep(), and the ResizeObserver onMounted/
onUnmounted wiring were stateful logic with no direct template
dependency, inline in the component. Pulled into a composable built on
@vueuse/core's useScroll/useResizeObserver instead of hand-rolled scroll
tracking, following the reuse-before-you-write ladder.

Establishes src/composables/ and its conventions for later extractions:
individual refs returned (not a reactive() object, which breaks
destructuring), and a shared withSetup() test helper in
src/test-utils/ for composables that rely on onMounted/onUnmounted.

Also adds an aria-label identifying the scrollable region, closing the
a11y gap noted in #134 while touching this code (mis-cited there as
#59 — that's OfficeOverview's favourite-indicator issue instead; #134
should be corrected separately).

PR 1 of #134.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: James Manuel <moodyjmz@users.noreply.github.com>
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