Merged PR 1963: feat(utils): add scroll-top button component

feat(utils): add scroll-top button component

Add a reusable ScrollTopButtonComponent that provides smooth scrolling
to the top of a page or specific element. The component automatically
shows/hides based on scroll position and respects user's reduced motion
preferences.

Key features:
- Supports both window and element-specific scrolling
- Configurable position with sensible defaults
- Accessibility compliant with proper aria-label
- Respects prefers-reduced-motion media query
- Debounced scroll event handling for performance

Integrate the component into remission list and search dialog
components to improve user navigation experience.

Ref: #5360
This commit is contained in:
Nino Righi
2025-10-06 08:41:08 +00:00
committed by Lorenz Hilpert
parent 62e586cfda
commit d430f544f0
7 changed files with 230 additions and 2 deletions

View File

@@ -52,6 +52,9 @@
[hasValidSearchTerm]="hasValidSearchTerm()"
[hits]="hits()"
></remi-feature-remission-list-empty-state>
<utils-scroll-top-button
[position]="{ bottom: remissionStarted() ? '5.5rem' : '1.5rem' }"
></utils-scroll-top-button>
</div>
@if (remissionStarted()) {

View File

@@ -16,7 +16,10 @@ import {
FilterService,
SearchTrigger,
} from '@isa/shared/filter';
import { injectRestoreScrollPosition } from '@isa/utils/scroll-position';
import {
injectRestoreScrollPosition,
ScrollTopButtonComponent,
} from '@isa/utils/scroll-position';
import { RemissionStartCardComponent } from './remission-start-card/remission-start-card.component';
import { RemissionListSelectComponent } from './remission-list-select/remission-list-select.component';
import {
@@ -94,6 +97,7 @@ function querySettingsFactory() {
RemissionListDepartmentElementsComponent,
RemissionProcessedHintComponent,
RemissionListEmptyStateComponent,
ScrollTopButtonComponent,
],
host: {
'[class]':

View File

@@ -34,7 +34,7 @@
<ng-icon size="1.5rem" name="isaOtherInfo"></ng-icon>
</button>
</p>
<div class="overflow-y-auto overflow-x-hidden">
<div #list class="overflow-y-auto overflow-x-hidden">
@if (searchResource.value()?.result; as items) {
@for (item of availableSearchResults(); track item.id) {
@defer {
@@ -58,4 +58,5 @@
>
</ui-empty-state>
}
<utils-scroll-top-button [target]="list"></utils-scroll-top-button>
</div>

View File

@@ -32,6 +32,8 @@ import { TooltipDirective } from '@isa/ui/tooltip';
import { createInStockResource } from './instock.resource';
import { calculateAvailableStock } from '@isa/remission/data-access';
import { EmptyStateComponent } from '@isa/ui/empty-state';
import { ScrollTopButtonComponent } from '@isa/utils/scroll-position';
@Component({
selector: 'remi-search-item-to-remit-list',
templateUrl: './search-item-to-remit-list.component.html',
@@ -48,6 +50,7 @@ import { EmptyStateComponent } from '@isa/ui/empty-state';
TooltipDirective,
NgIcon,
EmptyStateComponent,
ScrollTopButtonComponent,
],
providers: [provideIcons({ isaActionSearch, isaOtherInfo })],
})