@aspect-ops/exon-ui 0.0.3 → 0.2.0

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.
Files changed (79) hide show
  1. package/README.md +929 -54
  2. package/dist/components/Accordion/Accordion.svelte +79 -0
  3. package/dist/components/Accordion/Accordion.svelte.d.ts +10 -0
  4. package/dist/components/Accordion/AccordionItem.svelte +198 -0
  5. package/dist/components/Accordion/AccordionItem.svelte.d.ts +10 -0
  6. package/dist/components/Accordion/index.d.ts +2 -0
  7. package/dist/components/Accordion/index.js +2 -0
  8. package/dist/components/Carousel/Carousel.svelte +454 -0
  9. package/dist/components/Carousel/Carousel.svelte.d.ts +14 -0
  10. package/dist/components/Carousel/CarouselSlide.svelte +22 -0
  11. package/dist/components/Carousel/CarouselSlide.svelte.d.ts +7 -0
  12. package/dist/components/Carousel/index.d.ts +2 -0
  13. package/dist/components/Carousel/index.js +2 -0
  14. package/dist/components/Chip/Chip.svelte +461 -0
  15. package/dist/components/Chip/Chip.svelte.d.ts +17 -0
  16. package/dist/components/Chip/ChipGroup.svelte +76 -0
  17. package/dist/components/Chip/ChipGroup.svelte.d.ts +9 -0
  18. package/dist/components/Chip/index.d.ts +2 -0
  19. package/dist/components/Chip/index.js +2 -0
  20. package/dist/components/DatePicker/DatePicker.svelte +746 -0
  21. package/dist/components/DatePicker/DatePicker.svelte.d.ts +19 -0
  22. package/dist/components/DatePicker/index.d.ts +1 -0
  23. package/dist/components/DatePicker/index.js +1 -0
  24. package/dist/components/FileUpload/FileUpload.svelte +484 -0
  25. package/dist/components/FileUpload/FileUpload.svelte.d.ts +16 -0
  26. package/dist/components/FileUpload/index.d.ts +1 -0
  27. package/dist/components/FileUpload/index.js +1 -0
  28. package/dist/components/Image/Image.svelte +223 -0
  29. package/dist/components/Image/Image.svelte.d.ts +19 -0
  30. package/dist/components/Image/index.d.ts +1 -0
  31. package/dist/components/Image/index.js +1 -0
  32. package/dist/components/NumberInput/NumberInput.svelte +293 -0
  33. package/dist/components/NumberInput/NumberInput.svelte.d.ts +16 -0
  34. package/dist/components/NumberInput/index.d.ts +1 -0
  35. package/dist/components/NumberInput/index.js +1 -0
  36. package/dist/components/OTPInput/OTPInput.svelte +312 -0
  37. package/dist/components/OTPInput/OTPInput.svelte.d.ts +57 -0
  38. package/dist/components/OTPInput/index.d.ts +1 -0
  39. package/dist/components/OTPInput/index.js +1 -0
  40. package/dist/components/Pagination/Pagination.svelte +243 -0
  41. package/dist/components/Pagination/Pagination.svelte.d.ts +10 -0
  42. package/dist/components/Pagination/index.d.ts +1 -0
  43. package/dist/components/Pagination/index.js +1 -0
  44. package/dist/components/Rating/Rating.svelte +316 -0
  45. package/dist/components/Rating/Rating.svelte.d.ts +16 -0
  46. package/dist/components/Rating/index.d.ts +1 -0
  47. package/dist/components/Rating/index.js +1 -0
  48. package/dist/components/SearchInput/SearchInput.svelte +480 -0
  49. package/dist/components/SearchInput/SearchInput.svelte.d.ts +22 -0
  50. package/dist/components/SearchInput/index.d.ts +1 -0
  51. package/dist/components/SearchInput/index.js +1 -0
  52. package/dist/components/Slider/Slider.svelte +324 -0
  53. package/dist/components/Slider/Slider.svelte.d.ts +14 -0
  54. package/dist/components/Slider/index.d.ts +1 -0
  55. package/dist/components/Slider/index.js +1 -0
  56. package/dist/components/Stepper/Stepper.svelte +100 -0
  57. package/dist/components/Stepper/Stepper.svelte.d.ts +11 -0
  58. package/dist/components/Stepper/StepperStep.svelte +391 -0
  59. package/dist/components/Stepper/StepperStep.svelte.d.ts +13 -0
  60. package/dist/components/Stepper/index.d.ts +2 -0
  61. package/dist/components/Stepper/index.js +2 -0
  62. package/dist/components/TimePicker/TimePicker.svelte +803 -0
  63. package/dist/components/TimePicker/TimePicker.svelte.d.ts +17 -0
  64. package/dist/components/TimePicker/index.d.ts +1 -0
  65. package/dist/components/TimePicker/index.js +1 -0
  66. package/dist/components/ToggleGroup/ToggleGroup.svelte +91 -0
  67. package/dist/components/ToggleGroup/ToggleGroup.svelte.d.ts +13 -0
  68. package/dist/components/ToggleGroup/ToggleGroupItem.svelte +158 -0
  69. package/dist/components/ToggleGroup/ToggleGroupItem.svelte.d.ts +9 -0
  70. package/dist/components/ToggleGroup/index.d.ts +3 -0
  71. package/dist/components/ToggleGroup/index.js +2 -0
  72. package/dist/index.d.ts +13 -1
  73. package/dist/index.js +12 -0
  74. package/dist/types/data-display.d.ts +68 -0
  75. package/dist/types/index.d.ts +3 -2
  76. package/dist/types/input.d.ts +82 -0
  77. package/dist/types/input.js +2 -0
  78. package/dist/types/navigation.d.ts +15 -0
  79. package/package.json +1 -1
@@ -0,0 +1,312 @@
1
+ <script lang="ts">
2
+ import { onMount } from 'svelte';
3
+
4
+ interface Props {
5
+ /**
6
+ * The OTP value (bindable)
7
+ * @default ''
8
+ */
9
+ value?: string;
10
+
11
+ /**
12
+ * Number of OTP digits
13
+ * @default 6
14
+ */
15
+ length?: number;
16
+
17
+ /**
18
+ * Input type validation
19
+ * @default 'numeric'
20
+ */
21
+ type?: 'numeric' | 'alphanumeric';
22
+
23
+ /**
24
+ * Show dots instead of characters
25
+ * @default false
26
+ */
27
+ masked?: boolean;
28
+
29
+ /**
30
+ * Disabled state
31
+ * @default false
32
+ */
33
+ disabled?: boolean;
34
+
35
+ /**
36
+ * Error state
37
+ * @default false
38
+ */
39
+ error?: boolean;
40
+
41
+ /**
42
+ * Component size
43
+ * @default 'md'
44
+ */
45
+ size?: 'sm' | 'md' | 'lg';
46
+
47
+ /**
48
+ * Auto-focus first input on mount
49
+ * @default false
50
+ */
51
+ autoFocus?: boolean;
52
+
53
+ /**
54
+ * Additional CSS classes
55
+ */
56
+ class?: string;
57
+
58
+ /**
59
+ * Callback when all digits are entered
60
+ */
61
+ oncomplete?: (value: string) => void;
62
+
63
+ /**
64
+ * Callback on value change
65
+ */
66
+ onchange?: (value: string) => void;
67
+ }
68
+
69
+ let {
70
+ value = $bindable(''),
71
+ length = 6,
72
+ type = 'numeric',
73
+ masked = false,
74
+ disabled = false,
75
+ error = false,
76
+ size = 'md',
77
+ autoFocus = false,
78
+ class: className = '',
79
+ oncomplete,
80
+ onchange
81
+ }: Props = $props();
82
+
83
+ // Track individual input elements
84
+ let inputs: (HTMLInputElement | null)[] = $state([]);
85
+
86
+ // Split value into individual characters
87
+ let chars = $derived(value.padEnd(length, ' ').slice(0, length).split(''));
88
+
89
+ onMount(() => {
90
+ if (autoFocus && inputs[0]) {
91
+ inputs[0].focus();
92
+ }
93
+ });
94
+
95
+ function handleInput(index: number, e: Event) {
96
+ const input = e.target as HTMLInputElement;
97
+ const char = input.value.slice(-1); // Get last character entered
98
+
99
+ // Validate based on type
100
+ if (type === 'numeric' && char && !/^\d$/.test(char)) {
101
+ input.value = '';
102
+ return;
103
+ }
104
+
105
+ if (type === 'alphanumeric' && char && !/^[a-zA-Z0-9]$/.test(char)) {
106
+ input.value = '';
107
+ return;
108
+ }
109
+
110
+ // Update value
111
+ const newChars = chars.map((c, i) => (i === index ? char : c));
112
+ const newValue = newChars.join('').trim();
113
+ value = newValue;
114
+
115
+ // Call onchange callback
116
+ onchange?.(newValue);
117
+
118
+ // Move to next input if character was entered
119
+ if (char && index < length - 1) {
120
+ inputs[index + 1]?.focus();
121
+ }
122
+
123
+ // Check completion
124
+ if (newValue.length === length) {
125
+ oncomplete?.(newValue);
126
+ }
127
+ }
128
+
129
+ function handleKeydown(index: number, e: KeyboardEvent) {
130
+ const input = e.target as HTMLInputElement;
131
+
132
+ switch (e.key) {
133
+ case 'Backspace':
134
+ // If input is empty, move to previous input
135
+ if (!input.value && index > 0) {
136
+ e.preventDefault();
137
+ inputs[index - 1]?.focus();
138
+ // Clear previous input
139
+ const newChars = chars.map((c, i) => (i === index - 1 ? '' : c));
140
+ value = newChars.join('').trim();
141
+ onchange?.(value);
142
+ }
143
+ break;
144
+
145
+ case 'ArrowLeft':
146
+ e.preventDefault();
147
+ if (index > 0) {
148
+ inputs[index - 1]?.focus();
149
+ }
150
+ break;
151
+
152
+ case 'ArrowRight':
153
+ e.preventDefault();
154
+ if (index < length - 1) {
155
+ inputs[index + 1]?.focus();
156
+ }
157
+ break;
158
+
159
+ case 'ArrowUp':
160
+ case 'ArrowDown':
161
+ // Prevent default to avoid number spinner in numeric inputs
162
+ e.preventDefault();
163
+ break;
164
+ }
165
+ }
166
+
167
+ function handlePaste(e: ClipboardEvent) {
168
+ e.preventDefault();
169
+ const pastedData = e.clipboardData?.getData('text') || '';
170
+
171
+ // Filter based on type
172
+ let filteredData = pastedData;
173
+ if (type === 'numeric') {
174
+ filteredData = pastedData.replace(/\D/g, '');
175
+ } else if (type === 'alphanumeric') {
176
+ filteredData = pastedData.replace(/[^a-zA-Z0-9]/g, '');
177
+ }
178
+
179
+ // Trim to length and update value
180
+ const newValue = filteredData.slice(0, length);
181
+ value = newValue;
182
+ onchange?.(newValue);
183
+
184
+ // Focus the next empty input or the last input
185
+ const nextEmptyIndex = newValue.length < length ? newValue.length : length - 1;
186
+ setTimeout(() => {
187
+ inputs[nextEmptyIndex]?.focus();
188
+ }, 0);
189
+
190
+ // Check completion
191
+ if (newValue.length === length) {
192
+ oncomplete?.(newValue);
193
+ }
194
+ }
195
+
196
+ function handleFocus(index: number, e: FocusEvent) {
197
+ const input = e.target as HTMLInputElement;
198
+ // Select content on focus for easy replacement
199
+ input.select();
200
+ }
201
+ </script>
202
+
203
+ <div
204
+ class="otp-input otp-input--{size} {error ? 'otp-input--error' : ''} {disabled
205
+ ? 'otp-input--disabled'
206
+ : ''} {className}"
207
+ role="group"
208
+ aria-label="One-time password input"
209
+ >
210
+ {#each Array(length) as _, index (index)}
211
+ <input
212
+ bind:this={inputs[index]}
213
+ class="otp-input__field"
214
+ type={masked ? 'password' : 'text'}
215
+ inputmode={type === 'numeric' ? 'numeric' : 'text'}
216
+ autocomplete="one-time-code"
217
+ maxlength="1"
218
+ value={chars[index]?.trim() || ''}
219
+ aria-label="Digit {index + 1} of {length}"
220
+ aria-invalid={error}
221
+ {disabled}
222
+ oninput={(e) => handleInput(index, e)}
223
+ onkeydown={(e) => handleKeydown(index, e)}
224
+ onpaste={(e) => handlePaste(e)}
225
+ onfocus={(e) => handleFocus(index, e)}
226
+ />
227
+ {/each}
228
+ </div>
229
+
230
+ <style>
231
+ .otp-input {
232
+ display: flex;
233
+ gap: var(--space-sm, 0.5rem);
234
+ align-items: center;
235
+ width: 100%;
236
+ }
237
+
238
+ .otp-input--disabled {
239
+ opacity: 0.5;
240
+ }
241
+
242
+ .otp-input__field {
243
+ flex: 1;
244
+ min-width: 0;
245
+ min-height: var(--touch-target-min, 44px);
246
+ max-width: 3rem;
247
+ padding: var(--space-sm, 0.5rem);
248
+ border: 1px solid var(--color-border, #e5e7eb);
249
+ border-radius: var(--radius-md, 0.375rem);
250
+ background: var(--color-bg, #ffffff);
251
+ color: var(--color-text, #1f2937);
252
+ font-family: inherit;
253
+ font-size: var(--text-lg, 1.125rem);
254
+ font-weight: var(--font-semibold, 600);
255
+ text-align: center;
256
+ line-height: 1;
257
+ transition:
258
+ border-color var(--transition-fast, 150ms ease),
259
+ box-shadow var(--transition-fast, 150ms ease);
260
+ -webkit-tap-highlight-color: transparent;
261
+ }
262
+
263
+ .otp-input__field:focus {
264
+ outline: none;
265
+ border-color: var(--color-primary, #3b82f6);
266
+ box-shadow: 0 0 0 3px var(--color-primary-alpha, rgba(59, 130, 246, 0.1));
267
+ }
268
+
269
+ .otp-input__field:disabled {
270
+ background: var(--color-bg-muted, #f3f4f6);
271
+ cursor: not-allowed;
272
+ }
273
+
274
+ /* Size variants */
275
+ .otp-input--sm .otp-input__field {
276
+ min-height: var(--touch-target-min, 44px);
277
+ max-width: 2.5rem;
278
+ padding: var(--space-xs, 0.25rem);
279
+ font-size: var(--text-base, 1rem);
280
+ }
281
+
282
+ .otp-input--md .otp-input__field {
283
+ min-height: var(--touch-target-min, 44px);
284
+ max-width: 3rem;
285
+ padding: var(--space-sm, 0.5rem);
286
+ font-size: var(--text-lg, 1.125rem);
287
+ }
288
+
289
+ .otp-input--lg .otp-input__field {
290
+ min-height: 3.25rem;
291
+ max-width: 3.5rem;
292
+ padding: var(--space-md, 1rem);
293
+ font-size: var(--text-xl, 1.25rem);
294
+ }
295
+
296
+ /* Error state */
297
+ .otp-input--error .otp-input__field {
298
+ border-color: var(--color-error, #ef4444);
299
+ }
300
+
301
+ .otp-input--error .otp-input__field:focus {
302
+ border-color: var(--color-error, #ef4444);
303
+ box-shadow: 0 0 0 3px var(--color-error-alpha, rgba(239, 68, 68, 0.1));
304
+ }
305
+
306
+ /* Remove number spinner for numeric inputs */
307
+ .otp-input__field::-webkit-outer-spin-button,
308
+ .otp-input__field::-webkit-inner-spin-button {
309
+ -webkit-appearance: none;
310
+ margin: 0;
311
+ }
312
+ </style>
@@ -0,0 +1,57 @@
1
+ interface Props {
2
+ /**
3
+ * The OTP value (bindable)
4
+ * @default ''
5
+ */
6
+ value?: string;
7
+ /**
8
+ * Number of OTP digits
9
+ * @default 6
10
+ */
11
+ length?: number;
12
+ /**
13
+ * Input type validation
14
+ * @default 'numeric'
15
+ */
16
+ type?: 'numeric' | 'alphanumeric';
17
+ /**
18
+ * Show dots instead of characters
19
+ * @default false
20
+ */
21
+ masked?: boolean;
22
+ /**
23
+ * Disabled state
24
+ * @default false
25
+ */
26
+ disabled?: boolean;
27
+ /**
28
+ * Error state
29
+ * @default false
30
+ */
31
+ error?: boolean;
32
+ /**
33
+ * Component size
34
+ * @default 'md'
35
+ */
36
+ size?: 'sm' | 'md' | 'lg';
37
+ /**
38
+ * Auto-focus first input on mount
39
+ * @default false
40
+ */
41
+ autoFocus?: boolean;
42
+ /**
43
+ * Additional CSS classes
44
+ */
45
+ class?: string;
46
+ /**
47
+ * Callback when all digits are entered
48
+ */
49
+ oncomplete?: (value: string) => void;
50
+ /**
51
+ * Callback on value change
52
+ */
53
+ onchange?: (value: string) => void;
54
+ }
55
+ declare const OTPInput: import("svelte").Component<Props, {}, "value">;
56
+ type OTPInput = ReturnType<typeof OTPInput>;
57
+ export default OTPInput;
@@ -0,0 +1 @@
1
+ export { default as OTPInput } from './OTPInput.svelte';
@@ -0,0 +1 @@
1
+ export { default as OTPInput } from './OTPInput.svelte';
@@ -0,0 +1,243 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ currentPage: number;
4
+ totalPages: number;
5
+ siblingCount?: number;
6
+ onPageChange?: (page: number) => void;
7
+ class?: string;
8
+ }
9
+
10
+ let {
11
+ currentPage,
12
+ totalPages,
13
+ siblingCount = 1,
14
+ onPageChange,
15
+ class: className = ''
16
+ }: Props = $props();
17
+
18
+ const canGoPrevious = $derived(currentPage > 1);
19
+ const canGoNext = $derived(currentPage < totalPages);
20
+
21
+ // Generate page numbers with ellipsis logic
22
+ const pageNumbers = $derived(() => {
23
+ const pages: (number | 'ellipsis-start' | 'ellipsis-end')[] = [];
24
+
25
+ // Always show first page
26
+ pages.push(1);
27
+
28
+ // Calculate the range around current page
29
+ const leftSibling = Math.max(currentPage - siblingCount, 2);
30
+ const rightSibling = Math.min(currentPage + siblingCount, totalPages - 1);
31
+
32
+ // Add ellipsis after first page if needed
33
+ if (leftSibling > 2) {
34
+ pages.push('ellipsis-start');
35
+ }
36
+
37
+ // Add sibling pages
38
+ for (let i = leftSibling; i <= rightSibling; i++) {
39
+ pages.push(i);
40
+ }
41
+
42
+ // Add ellipsis before last page if needed
43
+ if (rightSibling < totalPages - 1) {
44
+ pages.push('ellipsis-end');
45
+ }
46
+
47
+ // Always show last page (if more than 1 page)
48
+ if (totalPages > 1) {
49
+ pages.push(totalPages);
50
+ }
51
+
52
+ return pages;
53
+ });
54
+
55
+ function handlePageClick(page: number) {
56
+ if (page !== currentPage && page >= 1 && page <= totalPages) {
57
+ onPageChange?.(page);
58
+ }
59
+ }
60
+
61
+ function handlePrevious() {
62
+ if (canGoPrevious) {
63
+ onPageChange?.(currentPage - 1);
64
+ }
65
+ }
66
+
67
+ function handleNext() {
68
+ if (canGoNext) {
69
+ onPageChange?.(currentPage + 1);
70
+ }
71
+ }
72
+
73
+ function handleKeyDown(event: KeyboardEvent) {
74
+ switch (event.key) {
75
+ case 'ArrowLeft':
76
+ event.preventDefault();
77
+ handlePrevious();
78
+ break;
79
+ case 'ArrowRight':
80
+ event.preventDefault();
81
+ handleNext();
82
+ break;
83
+ case 'Home':
84
+ event.preventDefault();
85
+ handlePageClick(1);
86
+ break;
87
+ case 'End':
88
+ event.preventDefault();
89
+ handlePageClick(totalPages);
90
+ break;
91
+ }
92
+ }
93
+ </script>
94
+
95
+ <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
96
+ <nav class="pagination {className}" aria-label="Pagination">
97
+ <div class="pagination-wrapper" role="group" onkeydown={handleKeyDown}>
98
+ <button
99
+ class="pagination-button pagination-button--previous"
100
+ disabled={!canGoPrevious}
101
+ onclick={handlePrevious}
102
+ aria-label="Previous page"
103
+ >
104
+ Previous
105
+ </button>
106
+
107
+ <div class="pagination-pages">
108
+ {#each pageNumbers() as item}
109
+ {#if typeof item === 'number'}
110
+ <button
111
+ class="pagination-button pagination-button--page"
112
+ class:pagination-button--current={item === currentPage}
113
+ onclick={() => handlePageClick(item)}
114
+ aria-label={item === currentPage ? `Current page, page ${item}` : `Go to page ${item}`}
115
+ aria-current={item === currentPage ? 'page' : undefined}
116
+ >
117
+ {item}
118
+ </button>
119
+ {:else}
120
+ <span class="pagination-ellipsis" aria-hidden="true">...</span>
121
+ {/if}
122
+ {/each}
123
+ </div>
124
+
125
+ <button
126
+ class="pagination-button pagination-button--next"
127
+ disabled={!canGoNext}
128
+ onclick={handleNext}
129
+ aria-label="Next page"
130
+ >
131
+ Next
132
+ </button>
133
+ </div>
134
+ </nav>
135
+
136
+ <style>
137
+ .pagination {
138
+ font-family: inherit;
139
+ }
140
+
141
+ .pagination-wrapper {
142
+ display: flex;
143
+ align-items: center;
144
+ gap: 0.5rem;
145
+ }
146
+
147
+ .pagination-pages {
148
+ display: flex;
149
+ align-items: center;
150
+ gap: 0.25rem;
151
+ }
152
+
153
+ .pagination-button {
154
+ min-width: 2.75rem;
155
+ min-height: 2.75rem; /* 44px minimum touch target */
156
+ padding: 0.5rem 0.75rem;
157
+ border: 1px solid var(--pagination-border-color, #d1d5db);
158
+ border-radius: var(--pagination-border-radius, 0.375rem);
159
+ background-color: var(--pagination-bg-color, #ffffff);
160
+ color: var(--pagination-text-color, #374151);
161
+ font-family: inherit;
162
+ font-size: 0.875rem;
163
+ font-weight: 500;
164
+ cursor: pointer;
165
+ transition: all 0.2s ease;
166
+ }
167
+
168
+ .pagination-button:hover:not(:disabled) {
169
+ background-color: var(--pagination-hover-bg-color, #f3f4f6);
170
+ border-color: var(--pagination-hover-border-color, #9ca3af);
171
+ }
172
+
173
+ .pagination-button:focus-visible {
174
+ outline: 2px solid var(--pagination-focus-color, #3b82f6);
175
+ outline-offset: 2px;
176
+ }
177
+
178
+ .pagination-button:disabled {
179
+ opacity: 0.5;
180
+ cursor: not-allowed;
181
+ }
182
+
183
+ .pagination-button--page {
184
+ min-width: 2.75rem;
185
+ }
186
+
187
+ .pagination-button--current {
188
+ background-color: var(--pagination-current-bg-color, #3b82f6);
189
+ color: var(--pagination-current-text-color, #ffffff);
190
+ border-color: var(--pagination-current-border-color, #3b82f6);
191
+ }
192
+
193
+ .pagination-button--current:hover {
194
+ background-color: var(--pagination-current-hover-bg-color, #2563eb);
195
+ border-color: var(--pagination-current-hover-border-color, #2563eb);
196
+ }
197
+
198
+ .pagination-button--previous,
199
+ .pagination-button--next {
200
+ padding-left: 1rem;
201
+ padding-right: 1rem;
202
+ }
203
+
204
+ .pagination-ellipsis {
205
+ display: inline-flex;
206
+ align-items: center;
207
+ justify-content: center;
208
+ min-width: 2.75rem;
209
+ min-height: 2.75rem;
210
+ padding: 0.5rem;
211
+ color: var(--pagination-ellipsis-color, #6b7280);
212
+ font-size: 0.875rem;
213
+ }
214
+
215
+ /* Mobile responsive: hide some siblings on small screens */
216
+ @media (max-width: 640px) {
217
+ .pagination-wrapper {
218
+ gap: 0.25rem;
219
+ }
220
+
221
+ .pagination-pages {
222
+ gap: 0.125rem;
223
+ }
224
+
225
+ .pagination-button--previous,
226
+ .pagination-button--next {
227
+ padding-left: 0.75rem;
228
+ padding-right: 0.75rem;
229
+ font-size: 0.75rem;
230
+ }
231
+
232
+ .pagination-button--page {
233
+ min-width: 2.75rem;
234
+ padding: 0.5rem;
235
+ font-size: 0.75rem;
236
+ }
237
+
238
+ .pagination-ellipsis {
239
+ min-width: 2rem;
240
+ padding: 0.25rem;
241
+ }
242
+ }
243
+ </style>
@@ -0,0 +1,10 @@
1
+ interface Props {
2
+ currentPage: number;
3
+ totalPages: number;
4
+ siblingCount?: number;
5
+ onPageChange?: (page: number) => void;
6
+ class?: string;
7
+ }
8
+ declare const Pagination: import("svelte").Component<Props, {}, "">;
9
+ type Pagination = ReturnType<typeof Pagination>;
10
+ export default Pagination;
@@ -0,0 +1 @@
1
+ export { default as Pagination } from './Pagination.svelte';
@@ -0,0 +1 @@
1
+ export { default as Pagination } from './Pagination.svelte';