@streamscloud/kit 0.0.1-1770823200886 → 0.0.1-1770841384222
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ui/infinite-scrolling/cmp.infinite-scrolling.svelte +79 -0
- package/dist/ui/infinite-scrolling/cmp.infinite-scrolling.svelte.d.ts +14 -0
- package/dist/ui/infinite-scrolling/index.d.ts +1 -0
- package/dist/ui/infinite-scrolling/index.js +1 -0
- package/dist/ui/loading/cmp.loading.svelte +82 -0
- package/dist/ui/loading/cmp.loading.svelte.d.ts +9 -0
- package/dist/ui/loading/index.d.ts +1 -0
- package/dist/ui/loading/index.js +1 -0
- package/dist/ui/proportional-container/cmp.proportional-container.svelte +25 -0
- package/dist/ui/proportional-container/cmp.proportional-container.svelte.d.ts +8 -0
- package/dist/ui/proportional-container/index.d.ts +1 -0
- package/dist/ui/proportional-container/index.js +1 -0
- package/package.json +13 -1
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<script lang="ts">import { Loading } from '../loading';
|
|
2
|
+
let { loadMore, container = null, actuationOffset = '', children, loading } = $props();
|
|
3
|
+
let isLoading = $state(false);
|
|
4
|
+
let paginationTrigger = $state(null);
|
|
5
|
+
let itemsContainer = $state(null);
|
|
6
|
+
$effect(() => {
|
|
7
|
+
if (!paginationTrigger || !itemsContainer) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const trigger = paginationTrigger;
|
|
11
|
+
const items = itemsContainer;
|
|
12
|
+
const intersectionObserver = new IntersectionObserver((e) => {
|
|
13
|
+
const [entries] = e;
|
|
14
|
+
if (entries.isIntersecting) {
|
|
15
|
+
void onLoadMore();
|
|
16
|
+
}
|
|
17
|
+
}, {
|
|
18
|
+
root: container,
|
|
19
|
+
rootMargin: actuationOffset
|
|
20
|
+
});
|
|
21
|
+
// Re-observe trigger on container resize to force IntersectionObserver
|
|
22
|
+
// to re-evaluate visibility — it won't fire on its own when siblings resize
|
|
23
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
24
|
+
intersectionObserver.unobserve(trigger);
|
|
25
|
+
intersectionObserver.observe(trigger);
|
|
26
|
+
});
|
|
27
|
+
resizeObserver.observe(items);
|
|
28
|
+
return () => {
|
|
29
|
+
resizeObserver.disconnect();
|
|
30
|
+
intersectionObserver.disconnect();
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
const onLoadMore = async () => {
|
|
34
|
+
if (isLoading) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
isLoading = true;
|
|
38
|
+
try {
|
|
39
|
+
await loadMore();
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
isLoading = false;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<div class="infinite-scrolling">
|
|
48
|
+
<div bind:this={itemsContainer}>
|
|
49
|
+
{@render children()}
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<div class="infinite-scrolling__pagination-trigger" bind:this={paginationTrigger}></div>
|
|
53
|
+
{#if isLoading}
|
|
54
|
+
{#if loading}
|
|
55
|
+
{@render loading()}
|
|
56
|
+
{:else}
|
|
57
|
+
<div class="infinite-scrolling__loading-container">
|
|
58
|
+
<Loading timeout={500} />
|
|
59
|
+
</div>
|
|
60
|
+
{/if}
|
|
61
|
+
{/if}
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
<style>.infinite-scrolling {
|
|
65
|
+
--_infinite-scrolling--overflow-y: var(--infinite-scrolling--overflow-y, initial);
|
|
66
|
+
overflow-y: var(--_infinite-scrolling--overflow-y);
|
|
67
|
+
min-height: 2.625em;
|
|
68
|
+
position: relative;
|
|
69
|
+
width: 100%;
|
|
70
|
+
}
|
|
71
|
+
.infinite-scrolling__pagination-trigger {
|
|
72
|
+
border: 1px solid transparent;
|
|
73
|
+
}
|
|
74
|
+
.infinite-scrolling__loading-container {
|
|
75
|
+
position: absolute;
|
|
76
|
+
bottom: 0.3125em;
|
|
77
|
+
left: 50%;
|
|
78
|
+
transform: translateX(-50%);
|
|
79
|
+
}</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
type Props = {
|
|
3
|
+
loadMore: () => Promise<unknown>;
|
|
4
|
+
/**
|
|
5
|
+
* Must be passed only if viewport is less than scrolling container
|
|
6
|
+
*/
|
|
7
|
+
container?: HTMLElement | null;
|
|
8
|
+
actuationOffset?: string;
|
|
9
|
+
children: Snippet;
|
|
10
|
+
loading?: Snippet;
|
|
11
|
+
};
|
|
12
|
+
declare const Cmp: import("svelte").Component<Props, {}, "">;
|
|
13
|
+
type Cmp = ReturnType<typeof Cmp>;
|
|
14
|
+
export default Cmp;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as InfiniteScrolling } from './cmp.infinite-scrolling.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as InfiniteScrolling } from './cmp.infinite-scrolling.svelte';
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<script lang="ts">let { positionFixedCenter = false, positionAbsoluteCenter = false, blocking = false, timeout = 0 } = $props();
|
|
2
|
+
let visible = $state(false);
|
|
3
|
+
$effect(() => {
|
|
4
|
+
const timer = setTimeout(() => (visible = true), timeout);
|
|
5
|
+
return () => clearTimeout(timer);
|
|
6
|
+
});
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
{#if visible && blocking}
|
|
10
|
+
<div class="loading-ring-overlay" class:loading-ring-overlay--fixed={positionFixedCenter}></div>
|
|
11
|
+
{/if}
|
|
12
|
+
|
|
13
|
+
<div
|
|
14
|
+
class="la-ball-clip-rotate"
|
|
15
|
+
class:la-ball-clip-rotate--absolute-center={positionAbsoluteCenter}
|
|
16
|
+
class:la-ball-clip-rotate--fixed-center={positionFixedCenter}
|
|
17
|
+
class:la-ball-clip-rotate--visible={visible}>
|
|
18
|
+
<div class="la-ball-clip-rotate__spin"></div>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<style>.loading-ring-overlay {
|
|
22
|
+
position: absolute;
|
|
23
|
+
inset: 0;
|
|
24
|
+
background-color: rgba(0, 0, 0, 0.3);
|
|
25
|
+
z-index: 999;
|
|
26
|
+
}
|
|
27
|
+
.loading-ring-overlay--fixed {
|
|
28
|
+
position: fixed;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.la-ball-clip-rotate {
|
|
32
|
+
--_loading--font-size: var(--loading--font-size, 1rem);
|
|
33
|
+
--_loading--spinner-color: var(--loading--spinner-color, light-dark(#144ab0, #5a8dec));
|
|
34
|
+
font-size: var(--_loading--font-size);
|
|
35
|
+
color: var(--_loading--spinner-color);
|
|
36
|
+
display: block;
|
|
37
|
+
opacity: 0;
|
|
38
|
+
width: 2em;
|
|
39
|
+
height: 2em;
|
|
40
|
+
z-index: 10;
|
|
41
|
+
}
|
|
42
|
+
.la-ball-clip-rotate--visible {
|
|
43
|
+
opacity: 1;
|
|
44
|
+
}
|
|
45
|
+
.la-ball-clip-rotate--absolute-center {
|
|
46
|
+
position: absolute;
|
|
47
|
+
top: 50%;
|
|
48
|
+
left: 50%;
|
|
49
|
+
transform: translate(-50%, -50%);
|
|
50
|
+
}
|
|
51
|
+
.la-ball-clip-rotate--fixed-center {
|
|
52
|
+
position: fixed;
|
|
53
|
+
top: 50%;
|
|
54
|
+
left: 50%;
|
|
55
|
+
transform: translate(-50%, -50%);
|
|
56
|
+
z-index: 1;
|
|
57
|
+
}
|
|
58
|
+
.la-ball-clip-rotate__spin {
|
|
59
|
+
position: relative;
|
|
60
|
+
box-sizing: border-box;
|
|
61
|
+
display: inline-block;
|
|
62
|
+
float: none;
|
|
63
|
+
border: 0.125em solid currentColor;
|
|
64
|
+
width: 2em;
|
|
65
|
+
height: 2em;
|
|
66
|
+
background: transparent;
|
|
67
|
+
border-bottom-color: transparent;
|
|
68
|
+
border-radius: 100%;
|
|
69
|
+
animation: ball-clip-rotate 0.75s linear infinite;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@keyframes ball-clip-rotate {
|
|
73
|
+
0% {
|
|
74
|
+
transform: rotate(0deg);
|
|
75
|
+
}
|
|
76
|
+
50% {
|
|
77
|
+
transform: rotate(180deg);
|
|
78
|
+
}
|
|
79
|
+
100% {
|
|
80
|
+
transform: rotate(360deg);
|
|
81
|
+
}
|
|
82
|
+
}</style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Loading } from './cmp.loading.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Loading } from './cmp.loading.svelte';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script lang="ts">let { ratio, children } = $props();
|
|
2
|
+
export {};
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<div class="proportional-container" style:--proportional-container--ratio={ratio}>
|
|
6
|
+
<div class="proportional-container__placer">
|
|
7
|
+
{@render children?.()}
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<style>.proportional-container {
|
|
12
|
+
--_proportional-container--ratio: var(--proportional-container--ratio, 1);
|
|
13
|
+
--_proportional-container--height: var(--proportional-container--height, auto);
|
|
14
|
+
--_proportional-container--width: var(--proportional-container--width, 100%);
|
|
15
|
+
width: var(--_proportional-container--width);
|
|
16
|
+
max-width: 100%;
|
|
17
|
+
height: var(--_proportional-container--height);
|
|
18
|
+
max-height: 100%;
|
|
19
|
+
aspect-ratio: var(--_proportional-container--ratio);
|
|
20
|
+
position: relative;
|
|
21
|
+
}
|
|
22
|
+
.proportional-container__placer {
|
|
23
|
+
position: absolute;
|
|
24
|
+
inset: 0;
|
|
25
|
+
}</style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as ProportionalContainer } from './cmp.proportional-container.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as ProportionalContainer } from './cmp.proportional-container.svelte';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@streamscloud/kit",
|
|
3
|
-
"version": "0.0.1-
|
|
3
|
+
"version": "0.0.1-1770841384222",
|
|
4
4
|
"author": "StreamsCloud",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -88,6 +88,18 @@
|
|
|
88
88
|
"types": "./dist/ui/image/index.d.ts",
|
|
89
89
|
"svelte": "./dist/ui/image/index.js"
|
|
90
90
|
},
|
|
91
|
+
"./infinite-scrolling": {
|
|
92
|
+
"types": "./dist/ui/infinite-scrolling/index.d.ts",
|
|
93
|
+
"svelte": "./dist/ui/infinite-scrolling/index.js"
|
|
94
|
+
},
|
|
95
|
+
"./loading": {
|
|
96
|
+
"types": "./dist/ui/loading/index.d.ts",
|
|
97
|
+
"svelte": "./dist/ui/loading/index.js"
|
|
98
|
+
},
|
|
99
|
+
"./proportional-container": {
|
|
100
|
+
"types": "./dist/ui/proportional-container/index.d.ts",
|
|
101
|
+
"svelte": "./dist/ui/proportional-container/index.js"
|
|
102
|
+
},
|
|
91
103
|
"./core/media": {
|
|
92
104
|
"types": "./dist/core/media/index.d.ts",
|
|
93
105
|
"svelte": "./dist/core/media/index.js"
|