feature/ux-improvements #26
@@ -3,7 +3,7 @@
|
||||
- Renders a virtualized list of fonts
|
||||
- Handles font registration with the manager
|
||||
-->
|
||||
<script lang="ts" generics="T extends UnifiedFont">
|
||||
<script lang="ts">
|
||||
import {
|
||||
Skeleton,
|
||||
VirtualList,
|
||||
@@ -11,26 +11,23 @@ import {
|
||||
import type { ComponentProps } from 'svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import { getFontUrl } from '../../lib';
|
||||
import type { FontConfigRequest } from '../../model';
|
||||
import {
|
||||
type FontConfigRequest,
|
||||
type UnifiedFont,
|
||||
appliedFontsManager,
|
||||
unifiedFontStore,
|
||||
} from '../../model';
|
||||
|
||||
interface Props extends
|
||||
Omit<
|
||||
ComponentProps<typeof VirtualList<T>>,
|
||||
'onVisibleItemsChange'
|
||||
ComponentProps<typeof VirtualList<UnifiedFont>>,
|
||||
'items' | 'total' | 'isLoading' | 'onVisibleItemsChange' | 'onNearBottom'
|
||||
>
|
||||
{
|
||||
/**
|
||||
* Callback for when visible items change
|
||||
*/
|
||||
onVisibleItemsChange?: (items: T[]) => void;
|
||||
/**
|
||||
* Callback for when near bottom is reached
|
||||
*/
|
||||
onNearBottom?: (lastVisibleIndex: number) => void;
|
||||
onVisibleItemsChange?: (items: UnifiedFont[]) => void;
|
||||
/**
|
||||
* Weight of the font
|
||||
*/
|
||||
@@ -38,23 +35,20 @@ interface Props extends
|
||||
* Weight of the font
|
||||
*/
|
||||
weight: number;
|
||||
/**
|
||||
* Whether the list is in a loading state
|
||||
*/
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
let {
|
||||
items,
|
||||
children,
|
||||
onVisibleItemsChange,
|
||||
onNearBottom,
|
||||
weight,
|
||||
isLoading = false,
|
||||
...rest
|
||||
}: Props = $props();
|
||||
|
||||
function handleInternalVisibleChange(visibleItems: T[]) {
|
||||
const isLoading = $derived(
|
||||
unifiedFontStore.isFetching || unifiedFontStore.isLoading,
|
||||
);
|
||||
|
||||
function handleInternalVisibleChange(visibleItems: UnifiedFont[]) {
|
||||
const configs: FontConfigRequest[] = [];
|
||||
|
||||
visibleItems.forEach(item => {
|
||||
@@ -77,9 +71,32 @@ function handleInternalVisibleChange(visibleItems: T[]) {
|
||||
// onVisibleItemsChange?.(visibleItems);
|
||||
}
|
||||
|
||||
function handleNearBottom(lastVisibleIndex: number) {
|
||||
// Forward the call to any external listener
|
||||
onNearBottom?.(lastVisibleIndex);
|
||||
/**
|
||||
* Load more fonts by moving to the next page
|
||||
*/
|
||||
function loadMore() {
|
||||
if (
|
||||
!unifiedFontStore.pagination.hasMore
|
||||
|| unifiedFontStore.isFetching
|
||||
) {
|
||||
return;
|
||||
}
|
||||
unifiedFontStore.nextPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle scroll near bottom - auto-load next page
|
||||
*
|
||||
* Triggered by VirtualList when the user scrolls within 5 items of the end
|
||||
* of the loaded items. Only fetches if there are more pages available.
|
||||
*/
|
||||
function handleNearBottom(_lastVisibleIndex: number) {
|
||||
const { hasMore } = unifiedFontStore.pagination;
|
||||
|
||||
// VirtualList already checks if we're near the bottom of loaded items
|
||||
if (hasMore && !unifiedFontStore.isFetching) {
|
||||
loadMore();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -99,10 +116,11 @@ function handleNearBottom(lastVisibleIndex: number) {
|
||||
</div>
|
||||
{:else}
|
||||
<VirtualList
|
||||
{items}
|
||||
{...rest}
|
||||
items={unifiedFontStore.fonts}
|
||||
total={unifiedFontStore.pagination.total}
|
||||
onVisibleItemsChange={handleInternalVisibleChange}
|
||||
onNearBottom={handleNearBottom}
|
||||
{...rest}
|
||||
>
|
||||
{#snippet children(scope)}
|
||||
{@render children(scope)}
|
||||
|
||||
@@ -24,38 +24,6 @@ let innerHeight = $state(0);
|
||||
// Is the component above the middle of the viewport?
|
||||
let isAboveMiddle = $state(false);
|
||||
|
||||
const isLoading = $derived(
|
||||
unifiedFontStore.isFetching || unifiedFontStore.isLoading,
|
||||
);
|
||||
|
||||
/**
|
||||
* Load more fonts by moving to the next page
|
||||
*/
|
||||
function loadMore() {
|
||||
if (
|
||||
!unifiedFontStore.pagination.hasMore
|
||||
|| unifiedFontStore.isFetching
|
||||
) {
|
||||
return;
|
||||
}
|
||||
unifiedFontStore.nextPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle scroll near bottom - auto-load next page
|
||||
*
|
||||
* Triggered by VirtualList when the user scrolls within 5 items of the end
|
||||
* of the loaded items. Only fetches if there are more pages available.
|
||||
*/
|
||||
function handleNearBottom(_lastVisibleIndex: number) {
|
||||
const { hasMore } = unifiedFontStore.pagination;
|
||||
|
||||
// VirtualList already checks if we're near the bottom of loaded items
|
||||
if (hasMore && !unifiedFontStore.isFetching) {
|
||||
loadMore();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate display range for pagination info
|
||||
*/
|
||||
@@ -83,13 +51,9 @@ const checkPosition = throttle(() => {
|
||||
|
||||
<div bind:this={wrapper}>
|
||||
<FontVirtualList
|
||||
items={unifiedFontStore.fonts}
|
||||
total={unifiedFontStore.pagination.total}
|
||||
onNearBottom={handleNearBottom}
|
||||
itemHeight={220}
|
||||
useWindowScroll={true}
|
||||
weight={controlManager.weight}
|
||||
{isLoading}
|
||||
>
|
||||
{#snippet children({
|
||||
item: font,
|
||||
|
||||
Reference in New Issue
Block a user