@x33025/sveltely 0.0.39 → 0.0.41
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.
|
@@ -25,11 +25,7 @@
|
|
|
25
25
|
}
|
|
26
26
|
</script>
|
|
27
27
|
|
|
28
|
-
<button
|
|
29
|
-
onclick={handleClick}
|
|
30
|
-
class="rounded p-1.5 hover:bg-zinc-100 {className}"
|
|
31
|
-
title="Toggle {side} sidebar"
|
|
32
|
-
>
|
|
28
|
+
<button onclick={handleClick} class="sidebar-toggle {className}" title="Toggle {side} sidebar">
|
|
33
29
|
{#if children}
|
|
34
30
|
{@render children()}
|
|
35
31
|
{:else if side === 'left'}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { goto } from '$app/navigation';
|
|
3
|
+
import {
|
|
4
|
+
ChevronLeftIcon,
|
|
5
|
+
ChevronRightIcon,
|
|
6
|
+
ChevronsLeftIcon,
|
|
7
|
+
ChevronsRightIcon
|
|
8
|
+
} from '@lucide/svelte';
|
|
3
9
|
|
|
4
10
|
type PaginationData = {
|
|
5
11
|
view: string;
|
|
@@ -11,10 +17,14 @@
|
|
|
11
17
|
let {
|
|
12
18
|
data,
|
|
13
19
|
onPageChange,
|
|
20
|
+
showFirstLast = false,
|
|
21
|
+
style: styleMode = 'label',
|
|
14
22
|
class: className = ''
|
|
15
23
|
}: {
|
|
16
24
|
data: PaginationData;
|
|
17
25
|
onPageChange?: (page: number, href: string) => void | Promise<void>;
|
|
26
|
+
showFirstLast?: boolean;
|
|
27
|
+
style?: 'icon' | 'label';
|
|
18
28
|
class?: string;
|
|
19
29
|
} = $props();
|
|
20
30
|
|
|
@@ -31,6 +41,11 @@
|
|
|
31
41
|
const maxPage = () => Math.max(1, data.totalPages);
|
|
32
42
|
const safePage = () => Math.min(Math.max(data.page, 1), maxPage());
|
|
33
43
|
const hasNext = () => (typeof data.hasNext === 'boolean' ? data.hasNext : safePage() < maxPage());
|
|
44
|
+
const hasPrevious = () => safePage() > 1;
|
|
45
|
+
const buttonClass = () =>
|
|
46
|
+
`pagination-button action disabled:bg-zinc-200 disabled:text-zinc-500 inline-flex items-center justify-center leading-none ${
|
|
47
|
+
styleMode === 'icon' ? 'h-8 w-8 p-0' : 'padding-sm'
|
|
48
|
+
}`;
|
|
34
49
|
|
|
35
50
|
const goToPage = (targetPage: number) => {
|
|
36
51
|
const clamped = clampedPage(targetPage);
|
|
@@ -58,18 +73,36 @@
|
|
|
58
73
|
</script>
|
|
59
74
|
|
|
60
75
|
<div class={`hstack items-center ${className}`} style="gap: var(--pagination-gap);">
|
|
61
|
-
{#if
|
|
76
|
+
{#if showFirstLast}
|
|
62
77
|
<button
|
|
63
78
|
type="button"
|
|
64
|
-
class=
|
|
65
|
-
onclick={() => goToPage(
|
|
79
|
+
class={buttonClass()}
|
|
80
|
+
onclick={() => goToPage(1)}
|
|
81
|
+
aria-label="First page"
|
|
82
|
+
disabled={!hasPrevious()}
|
|
66
83
|
>
|
|
67
|
-
|
|
84
|
+
{#if styleMode === 'icon'}
|
|
85
|
+
<ChevronsLeftIcon class="size-4" />
|
|
86
|
+
{:else}
|
|
87
|
+
First
|
|
88
|
+
{/if}
|
|
68
89
|
</button>
|
|
69
|
-
{:else}
|
|
70
|
-
<span class="pagination-button action padding-sm bg-zinc-400">Previous</span>
|
|
71
90
|
{/if}
|
|
72
91
|
|
|
92
|
+
<button
|
|
93
|
+
type="button"
|
|
94
|
+
class={buttonClass()}
|
|
95
|
+
onclick={() => goToPage(safePage() - 1)}
|
|
96
|
+
aria-label="Previous page"
|
|
97
|
+
disabled={!hasPrevious()}
|
|
98
|
+
>
|
|
99
|
+
{#if styleMode === 'icon'}
|
|
100
|
+
<ChevronLeftIcon class="size-4" />
|
|
101
|
+
{:else}
|
|
102
|
+
Previous
|
|
103
|
+
{/if}
|
|
104
|
+
</button>
|
|
105
|
+
|
|
73
106
|
<span>Page</span>
|
|
74
107
|
|
|
75
108
|
<form method="GET" style="display: inline;" novalidate onsubmit={handleSubmit}>
|
|
@@ -79,15 +112,33 @@
|
|
|
79
112
|
|
|
80
113
|
<span>of {maxPage()}</span>
|
|
81
114
|
|
|
82
|
-
|
|
115
|
+
<button
|
|
116
|
+
type="button"
|
|
117
|
+
class={buttonClass()}
|
|
118
|
+
onclick={() => goToPage(safePage() + 1)}
|
|
119
|
+
aria-label="Next page"
|
|
120
|
+
disabled={!hasNext()}
|
|
121
|
+
>
|
|
122
|
+
{#if styleMode === 'icon'}
|
|
123
|
+
<ChevronRightIcon class="size-4" />
|
|
124
|
+
{:else}
|
|
125
|
+
Next
|
|
126
|
+
{/if}
|
|
127
|
+
</button>
|
|
128
|
+
|
|
129
|
+
{#if showFirstLast}
|
|
83
130
|
<button
|
|
84
131
|
type="button"
|
|
85
|
-
class=
|
|
86
|
-
onclick={() => goToPage(
|
|
132
|
+
class={buttonClass()}
|
|
133
|
+
onclick={() => goToPage(maxPage())}
|
|
134
|
+
aria-label="Last page"
|
|
135
|
+
disabled={!hasNext()}
|
|
87
136
|
>
|
|
88
|
-
|
|
137
|
+
{#if styleMode === 'icon'}
|
|
138
|
+
<ChevronsRightIcon class="size-4" />
|
|
139
|
+
{:else}
|
|
140
|
+
Last
|
|
141
|
+
{/if}
|
|
89
142
|
</button>
|
|
90
|
-
{:else}
|
|
91
|
-
<span class="pagination-button action padding-sm bg-zinc-400">Next</span>
|
|
92
143
|
{/if}
|
|
93
144
|
</div>
|
|
@@ -7,6 +7,8 @@ type PaginationData = {
|
|
|
7
7
|
type $$ComponentProps = {
|
|
8
8
|
data: PaginationData;
|
|
9
9
|
onPageChange?: (page: number, href: string) => void | Promise<void>;
|
|
10
|
+
showFirstLast?: boolean;
|
|
11
|
+
style?: 'icon' | 'label';
|
|
10
12
|
class?: string;
|
|
11
13
|
};
|
|
12
14
|
declare const Pagination: import("svelte").Component<$$ComponentProps, {}, "">;
|
package/dist/style/index.css
CHANGED
|
@@ -47,9 +47,19 @@
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
.pagination-button {
|
|
50
|
+
@apply rounded-full bg-zinc-100 p-1;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.pagination-button:disabled {
|
|
54
|
+
@apply cursor-not-allowed rounded-full p-1 opacity-50;
|
|
50
55
|
}
|
|
51
56
|
|
|
52
57
|
.pagination-input {
|
|
58
|
+
@apply w-[10ch] rounded-full bg-zinc-100 px-3 py-1 outline-none;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.sidebar-toggle {
|
|
62
|
+
@apply rounded p-1.5 hover:bg-zinc-100;
|
|
53
63
|
}
|
|
54
64
|
}
|
|
55
65
|
|
package/dist/style.css
CHANGED
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
--color-zinc-100: oklch(96.7% 0.001 286.375);
|
|
16
16
|
--color-zinc-200: oklch(92% 0.004 286.32);
|
|
17
17
|
--color-zinc-300: oklch(87.1% 0.006 286.286);
|
|
18
|
-
--color-zinc-400: oklch(70.5% 0.015 286.067);
|
|
19
18
|
--color-zinc-500: oklch(55.2% 0.016 285.938);
|
|
20
19
|
--color-zinc-700: oklch(37% 0.013 285.805);
|
|
21
20
|
--color-zinc-900: oklch(21% 0.006 285.885);
|
|
@@ -254,6 +253,9 @@
|
|
|
254
253
|
.h-5 {
|
|
255
254
|
height: calc(var(--spacing) * 5);
|
|
256
255
|
}
|
|
256
|
+
.h-8 {
|
|
257
|
+
height: calc(var(--spacing) * 8);
|
|
258
|
+
}
|
|
257
259
|
.h-full {
|
|
258
260
|
height: 100%;
|
|
259
261
|
}
|
|
@@ -263,6 +265,9 @@
|
|
|
263
265
|
.w-5 {
|
|
264
266
|
width: calc(var(--spacing) * 5);
|
|
265
267
|
}
|
|
268
|
+
.w-8 {
|
|
269
|
+
width: calc(var(--spacing) * 8);
|
|
270
|
+
}
|
|
266
271
|
.w-60 {
|
|
267
272
|
width: calc(var(--spacing) * 60);
|
|
268
273
|
}
|
|
@@ -367,11 +372,8 @@
|
|
|
367
372
|
.bg-zinc-50 {
|
|
368
373
|
background-color: var(--color-zinc-50);
|
|
369
374
|
}
|
|
370
|
-
.
|
|
371
|
-
|
|
372
|
-
}
|
|
373
|
-
.p-1\.5 {
|
|
374
|
-
padding: calc(var(--spacing) * 1.5);
|
|
375
|
+
.p-0 {
|
|
376
|
+
padding: calc(var(--spacing) * 0);
|
|
375
377
|
}
|
|
376
378
|
.p-2 {
|
|
377
379
|
padding: calc(var(--spacing) * 2);
|
|
@@ -401,6 +403,10 @@
|
|
|
401
403
|
font-size: var(--text-sm);
|
|
402
404
|
line-height: var(--tw-leading, var(--text-sm--line-height));
|
|
403
405
|
}
|
|
406
|
+
.leading-none {
|
|
407
|
+
--tw-leading: 1;
|
|
408
|
+
line-height: 1;
|
|
409
|
+
}
|
|
404
410
|
.font-medium {
|
|
405
411
|
--tw-font-weight: var(--font-weight-medium);
|
|
406
412
|
font-weight: var(--font-weight-medium);
|
|
@@ -527,6 +533,16 @@
|
|
|
527
533
|
cursor: not-allowed;
|
|
528
534
|
}
|
|
529
535
|
}
|
|
536
|
+
.disabled\:bg-zinc-200 {
|
|
537
|
+
&:disabled {
|
|
538
|
+
background-color: var(--color-zinc-200);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
.disabled\:text-zinc-500 {
|
|
542
|
+
&:disabled {
|
|
543
|
+
color: var(--color-zinc-500);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
530
546
|
.disabled\:opacity-40 {
|
|
531
547
|
&:disabled {
|
|
532
548
|
opacity: 40%;
|
|
@@ -583,6 +599,35 @@
|
|
|
583
599
|
.dropdown-item:hover {
|
|
584
600
|
background: var(--dropdown-item-highlight);
|
|
585
601
|
}
|
|
602
|
+
.pagination-button {
|
|
603
|
+
border-radius: calc(infinity * 1px);
|
|
604
|
+
background-color: var(--color-zinc-100);
|
|
605
|
+
padding: calc(var(--spacing) * 1);
|
|
606
|
+
}
|
|
607
|
+
.pagination-button:disabled {
|
|
608
|
+
cursor: not-allowed;
|
|
609
|
+
border-radius: calc(infinity * 1px);
|
|
610
|
+
padding: calc(var(--spacing) * 1);
|
|
611
|
+
opacity: 50%;
|
|
612
|
+
}
|
|
613
|
+
.pagination-input {
|
|
614
|
+
width: 10ch;
|
|
615
|
+
border-radius: calc(infinity * 1px);
|
|
616
|
+
background-color: var(--color-zinc-100);
|
|
617
|
+
padding-inline: calc(var(--spacing) * 3);
|
|
618
|
+
padding-block: calc(var(--spacing) * 1);
|
|
619
|
+
--tw-outline-style: none;
|
|
620
|
+
outline-style: none;
|
|
621
|
+
}
|
|
622
|
+
.sidebar-toggle {
|
|
623
|
+
border-radius: 0.25rem;
|
|
624
|
+
padding: calc(var(--spacing) * 1.5);
|
|
625
|
+
&:hover {
|
|
626
|
+
@media (hover: hover) {
|
|
627
|
+
background-color: var(--color-zinc-100);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
586
631
|
}
|
|
587
632
|
@layer theme {
|
|
588
633
|
:root {
|
|
@@ -680,6 +725,10 @@
|
|
|
680
725
|
inherits: false;
|
|
681
726
|
initial-value: solid;
|
|
682
727
|
}
|
|
728
|
+
@property --tw-leading {
|
|
729
|
+
syntax: "*";
|
|
730
|
+
inherits: false;
|
|
731
|
+
}
|
|
683
732
|
@property --tw-font-weight {
|
|
684
733
|
syntax: "*";
|
|
685
734
|
inherits: false;
|
|
@@ -890,6 +939,7 @@
|
|
|
890
939
|
--tw-skew-y: initial;
|
|
891
940
|
--tw-space-y-reverse: 0;
|
|
892
941
|
--tw-border-style: solid;
|
|
942
|
+
--tw-leading: initial;
|
|
893
943
|
--tw-font-weight: initial;
|
|
894
944
|
--tw-tracking: initial;
|
|
895
945
|
--tw-ordinal: initial;
|