@rkosafo/cai.components 0.0.78 → 0.0.80
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/README.md +8 -8
- package/dist/baseEditor/index.svelte +32 -32
- package/dist/builders/filters/FilterBuilder.svelte +641 -641
- package/dist/forms/FormCheckbox/FormCheckbox.svelte +53 -53
- package/dist/forms/FormClEditor/ClEdito.svelte +68 -68
- package/dist/forms/FormDatepicker/FormDatepicker.svelte +159 -159
- package/dist/forms/FormFileUpload/FormFileUplad.svelte +134 -134
- package/dist/forms/FormInput/FormInput.svelte +87 -87
- package/dist/forms/FormRadio/FormRadio.svelte +53 -53
- package/dist/forms/FormSelect/FormSelect.svelte +88 -88
- package/dist/forms/FormTextarea/FormTextarea.svelte +78 -78
- package/dist/forms/button-toggle/ButtonToggle.svelte +119 -119
- package/dist/forms/button-toggle/CheckIcon.svelte +28 -28
- package/dist/forms/checkbox/Checkbox.svelte +82 -82
- package/dist/forms/checkbox/CheckboxButton.svelte +92 -92
- package/dist/forms/datepicker/Datepicker.svelte +707 -707
- package/dist/forms/form/Form.svelte +69 -69
- package/dist/forms/input/Input.svelte +363 -363
- package/dist/forms/label/Label.svelte +38 -38
- package/dist/forms/radio/Radio.svelte +48 -48
- package/dist/forms/radio/RadioButton.svelte +22 -22
- package/dist/forms/select/Select.svelte +56 -56
- package/dist/forms/textarea/Textarea.svelte +165 -165
- package/dist/forms/toggle/Toggle.svelte +70 -70
- package/dist/layout/Chat/CategorySelector.svelte +52 -52
- package/dist/layout/Chat/ChatEntry.svelte +246 -246
- package/dist/layout/Chat/ChatEntrySkeleton.svelte +81 -81
- package/dist/layout/Chat/ChatHeader.svelte +172 -172
- package/dist/layout/Chat/ChatInput.svelte +207 -207
- package/dist/layout/Chat/DraggableWindow.svelte +230 -230
- package/dist/layout/Chat/PreviewPage.svelte +182 -182
- package/dist/layout/Chat/RichText.svelte +216 -216
- package/dist/layout/ComponentCanvas/Canvas.svelte +40 -40
- package/dist/layout/ComponentCanvas/ComponentRenderer.svelte +85 -85
- package/dist/layout/TF/Content/Content.svelte +21 -21
- package/dist/layout/TF/Header/Header.svelte +166 -166
- package/dist/layout/TF/Sidebar/Sidebar.svelte +148 -148
- package/dist/layout/TF/Wrapper/Wrapper.svelte +17 -17
- package/dist/layout/mailing/MailPaginator.svelte +36 -36
- package/dist/layout/mailing/MailSidebar.svelte +39 -39
- package/dist/layout/mailing/MailToolBar.svelte +174 -174
- package/dist/layout/mailing/MailingContent.svelte +10 -10
- package/dist/layout/mailing/MailingHeader.svelte +55 -55
- package/dist/layout/mailing/MailingMessageCard.svelte +112 -112
- package/dist/layout/mailing/MailingMessageViewer.svelte +87 -87
- package/dist/layout/mailing/MailingModule.svelte +448 -448
- package/dist/styles/docs.css +615 -615
- package/dist/styles/tf-layout.css +185 -185
- package/dist/themes/ThemeProvider.svelte +20 -20
- package/dist/types/index.d.ts +2 -0
- package/dist/typography/heading/Heading.svelte +35 -35
- package/dist/ui/accordion/Accordion.svelte +49 -49
- package/dist/ui/accordion/AccordionItem.svelte +173 -173
- package/dist/ui/alert/Alert.svelte +83 -83
- package/dist/ui/alertDialog/AlertDialog.svelte +40 -40
- package/dist/ui/avatar/Avatar.svelte +77 -77
- package/dist/ui/box/Box.svelte +28 -28
- package/dist/ui/breadcrumb/Breadcrumb.svelte +39 -39
- package/dist/ui/buttons/ActionButton.svelte +234 -234
- package/dist/ui/buttons/Button.svelte +102 -102
- package/dist/ui/buttons/GradientButton.svelte +59 -59
- package/dist/ui/datatable/Datatable.svelte +525 -525
- package/dist/ui/drawer/Drawer.svelte +300 -300
- package/dist/ui/dropdown/Dropdown.svelte +36 -36
- package/dist/ui/dropdown/DropdownDivider.svelte +11 -11
- package/dist/ui/dropdown/DropdownGroup.svelte +14 -14
- package/dist/ui/dropdown/DropdownHeader.svelte +14 -14
- package/dist/ui/dropdown/DropdownItem.svelte +52 -52
- package/dist/ui/footer/Footer.svelte +15 -15
- package/dist/ui/footer/FooterBrand.svelte +37 -37
- package/dist/ui/footer/FooterCopyright.svelte +45 -45
- package/dist/ui/footer/FooterIcon.svelte +22 -22
- package/dist/ui/footer/FooterLink.svelte +33 -33
- package/dist/ui/footer/FooterLinkGroup.svelte +13 -13
- package/dist/ui/icons/IconifyIcon.svelte +7 -7
- package/dist/ui/indicator/Indicator.svelte +42 -42
- package/dist/ui/modal/Modal.svelte +265 -265
- package/dist/ui/notificationList/NotificationList.svelte +123 -123
- package/dist/ui/pageLoader/PageLoader.svelte +14 -14
- package/dist/ui/pageLoader/PageLoader2.svelte +99 -0
- package/dist/ui/pageLoader/PageLoader2.svelte.d.ts +24 -0
- package/dist/ui/pageLoader/index.d.ts +2 -1
- package/dist/ui/pageLoader/index.js +2 -1
- package/dist/ui/paginate/Paginate.svelte +96 -96
- package/dist/ui/speedDial/SpeedDial.svelte +77 -77
- package/dist/ui/speedDial/SpeedDialButton.svelte +75 -75
- package/dist/ui/speedDial/SpeedDialTrigger.svelte +79 -79
- package/dist/ui/tab/Tab.svelte +93 -67
- package/dist/ui/table/Table.svelte +396 -396
- package/dist/ui/tableLoader/TableLoader.svelte +24 -24
- package/dist/ui/toast/Toast.svelte +337 -337
- package/dist/ui/toast/Toast.svelte.d.ts +10 -10
- package/dist/ui/toolbar/Toolbar.svelte +59 -59
- package/dist/ui/toolbar/ToolbarButton.svelte +56 -56
- package/dist/ui/toolbar/ToolbarGroup.svelte +43 -43
- package/dist/ui/tooltip/Tooltip.svelte +51 -51
- package/dist/utils/Popper.svelte +257 -257
- package/dist/utils/closeButton/CloseButton.svelte +88 -88
- package/dist/utils/index.d.ts +2 -2
- package/dist/utils/index.js +3 -3
- package/dist/utils/singleSelection.svelte.js +48 -48
- package/dist/youtube/index.svelte +12 -12
- package/package.json +1 -1
|
@@ -1,123 +1,123 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
<script lang="ts" generics="T extends NotificationItem">
|
|
4
|
-
import { Dropdown, DropdownItem } from '../dropdown/index.js';
|
|
5
|
-
import { Avatar } from '../avatar/index.js';
|
|
6
|
-
import { PageLoader, type NotificationItem, type NotificationListProps } from '../../index.js';
|
|
7
|
-
import { onDestroy, onMount } from 'svelte';
|
|
8
|
-
|
|
9
|
-
let {
|
|
10
|
-
open = $bindable(false),
|
|
11
|
-
onClearNotifications,
|
|
12
|
-
header,
|
|
13
|
-
busy = false,
|
|
14
|
-
data: initialData = [],
|
|
15
|
-
onclick,
|
|
16
|
-
footer,
|
|
17
|
-
read
|
|
18
|
-
}: NotificationListProps<T> = $props();
|
|
19
|
-
|
|
20
|
-
let data = $state(initialData);
|
|
21
|
-
let internalOpen = $state(false);
|
|
22
|
-
|
|
23
|
-
$effect(() => {
|
|
24
|
-
if (open !== undefined) {
|
|
25
|
-
internalOpen = open;
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
async function fetchData() {
|
|
30
|
-
if (!read) return;
|
|
31
|
-
|
|
32
|
-
try {
|
|
33
|
-
busy = true;
|
|
34
|
-
const result = await read();
|
|
35
|
-
data = result;
|
|
36
|
-
} finally {
|
|
37
|
-
busy = false;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
$effect(() => {
|
|
42
|
-
if (internalOpen) {
|
|
43
|
-
data = [];
|
|
44
|
-
fetchData();
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
onMount(() => {
|
|
49
|
-
if (initialData && initialData.length > 0) {
|
|
50
|
-
data = initialData;
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
onDestroy(() => {
|
|
55
|
-
data = [];
|
|
56
|
-
});
|
|
57
|
-
</script>
|
|
58
|
-
|
|
59
|
-
<Dropdown
|
|
60
|
-
bind:isOpen={internalOpen}
|
|
61
|
-
class="w-full max-w-sm divide-gray-100 rounded shadow dark:divide-gray-700 dark:bg-gray-800"
|
|
62
|
-
>
|
|
63
|
-
{#if header}
|
|
64
|
-
{@render header()}
|
|
65
|
-
{:else}
|
|
66
|
-
<div class="py-2 text-center font-bold">Notifications</div>
|
|
67
|
-
{/if}
|
|
68
|
-
<div
|
|
69
|
-
class="scrollbar-thumb-blue scrollbar-thumb-rounded scrollbar-track-blue-lighter scrollbar-w-2 scrolling-touch flex max-h-80 flex-col divide-y divide-gray-300 overflow-y-auto"
|
|
70
|
-
>
|
|
71
|
-
{#if busy}
|
|
72
|
-
<div class="flex h-52 w-96 items-center justify-center">
|
|
73
|
-
<PageLoader size={40} />
|
|
74
|
-
</div>
|
|
75
|
-
{:else if data.length}
|
|
76
|
-
{#each data as item, index}
|
|
77
|
-
<DropdownItem class="flex w-full space-x-4" onclick={() => onclick?.(item)}>
|
|
78
|
-
<Avatar cornerStyle="rounded">
|
|
79
|
-
<iconify-icon icon={item.icon} style="font-size: 20px;"></iconify-icon>
|
|
80
|
-
</Avatar>
|
|
81
|
-
<div class="w-full pl-3 text-start">
|
|
82
|
-
<div class="mb-1.5 text-sm text-gray-500 dark:text-gray-400">
|
|
83
|
-
<span class="font-semibold text-gray-900 dark:text-white">{item.sender}</span>: "{item.content}"
|
|
84
|
-
</div>
|
|
85
|
-
<div class="flex items-center justify-between">
|
|
86
|
-
<div class="text-xs text-primary-600 dark:text-primary-500">{item.time}</div>
|
|
87
|
-
<div class="flex items-center gap-1">
|
|
88
|
-
{#if item.isRead}
|
|
89
|
-
<span class="text-xs font-light text-gray-400">Read</span>
|
|
90
|
-
{/if}
|
|
91
|
-
<iconify-icon
|
|
92
|
-
icon={item.isRead ? 'ri:check-double-line' : 'uim:check'}
|
|
93
|
-
class={item.isRead ? 'text-blue-700' : 'text-gray-500'}
|
|
94
|
-
style="font-size: 18px;"
|
|
95
|
-
></iconify-icon>
|
|
96
|
-
</div>
|
|
97
|
-
</div>
|
|
98
|
-
</div>
|
|
99
|
-
</DropdownItem>
|
|
100
|
-
{/each}
|
|
101
|
-
{:else}
|
|
102
|
-
<div class="flex h-32 w-80 items-center justify-center space-x-4">
|
|
103
|
-
<p>No Notifications</p>
|
|
104
|
-
</div>
|
|
105
|
-
{/if}
|
|
106
|
-
</div>
|
|
107
|
-
{#if footer}
|
|
108
|
-
{@render footer()}
|
|
109
|
-
{:else}
|
|
110
|
-
<div
|
|
111
|
-
class="-my-1 block bg-gray-50 py-2 text-center text-sm font-medium text-gray-900 hover:bg-gray-100 dark:bg-gray-800 dark:text-white dark:hover:bg-gray-700"
|
|
112
|
-
>
|
|
113
|
-
{#if data.length}
|
|
114
|
-
<button class="w-full" onclick={onClearNotifications}>
|
|
115
|
-
<div class="inline-flex items-center gap-2">
|
|
116
|
-
<iconify-icon icon="ic:round-close"></iconify-icon>
|
|
117
|
-
Clear all
|
|
118
|
-
</div>
|
|
119
|
-
</button>
|
|
120
|
-
{/if}
|
|
121
|
-
</div>
|
|
122
|
-
{/if}
|
|
123
|
-
</Dropdown>
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
<script lang="ts" generics="T extends NotificationItem">
|
|
4
|
+
import { Dropdown, DropdownItem } from '../dropdown/index.js';
|
|
5
|
+
import { Avatar } from '../avatar/index.js';
|
|
6
|
+
import { PageLoader, type NotificationItem, type NotificationListProps } from '../../index.js';
|
|
7
|
+
import { onDestroy, onMount } from 'svelte';
|
|
8
|
+
|
|
9
|
+
let {
|
|
10
|
+
open = $bindable(false),
|
|
11
|
+
onClearNotifications,
|
|
12
|
+
header,
|
|
13
|
+
busy = false,
|
|
14
|
+
data: initialData = [],
|
|
15
|
+
onclick,
|
|
16
|
+
footer,
|
|
17
|
+
read
|
|
18
|
+
}: NotificationListProps<T> = $props();
|
|
19
|
+
|
|
20
|
+
let data = $state(initialData);
|
|
21
|
+
let internalOpen = $state(false);
|
|
22
|
+
|
|
23
|
+
$effect(() => {
|
|
24
|
+
if (open !== undefined) {
|
|
25
|
+
internalOpen = open;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
async function fetchData() {
|
|
30
|
+
if (!read) return;
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
busy = true;
|
|
34
|
+
const result = await read();
|
|
35
|
+
data = result;
|
|
36
|
+
} finally {
|
|
37
|
+
busy = false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
$effect(() => {
|
|
42
|
+
if (internalOpen) {
|
|
43
|
+
data = [];
|
|
44
|
+
fetchData();
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
onMount(() => {
|
|
49
|
+
if (initialData && initialData.length > 0) {
|
|
50
|
+
data = initialData;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
onDestroy(() => {
|
|
55
|
+
data = [];
|
|
56
|
+
});
|
|
57
|
+
</script>
|
|
58
|
+
|
|
59
|
+
<Dropdown
|
|
60
|
+
bind:isOpen={internalOpen}
|
|
61
|
+
class="w-full max-w-sm divide-gray-100 rounded shadow dark:divide-gray-700 dark:bg-gray-800"
|
|
62
|
+
>
|
|
63
|
+
{#if header}
|
|
64
|
+
{@render header()}
|
|
65
|
+
{:else}
|
|
66
|
+
<div class="py-2 text-center font-bold">Notifications</div>
|
|
67
|
+
{/if}
|
|
68
|
+
<div
|
|
69
|
+
class="scrollbar-thumb-blue scrollbar-thumb-rounded scrollbar-track-blue-lighter scrollbar-w-2 scrolling-touch flex max-h-80 flex-col divide-y divide-gray-300 overflow-y-auto"
|
|
70
|
+
>
|
|
71
|
+
{#if busy}
|
|
72
|
+
<div class="flex h-52 w-96 items-center justify-center">
|
|
73
|
+
<PageLoader size={40} />
|
|
74
|
+
</div>
|
|
75
|
+
{:else if data.length}
|
|
76
|
+
{#each data as item, index}
|
|
77
|
+
<DropdownItem class="flex w-full space-x-4" onclick={() => onclick?.(item)}>
|
|
78
|
+
<Avatar cornerStyle="rounded">
|
|
79
|
+
<iconify-icon icon={item.icon} style="font-size: 20px;"></iconify-icon>
|
|
80
|
+
</Avatar>
|
|
81
|
+
<div class="w-full pl-3 text-start">
|
|
82
|
+
<div class="mb-1.5 text-sm text-gray-500 dark:text-gray-400">
|
|
83
|
+
<span class="font-semibold text-gray-900 dark:text-white">{item.sender}</span>: "{item.content}"
|
|
84
|
+
</div>
|
|
85
|
+
<div class="flex items-center justify-between">
|
|
86
|
+
<div class="text-xs text-primary-600 dark:text-primary-500">{item.time}</div>
|
|
87
|
+
<div class="flex items-center gap-1">
|
|
88
|
+
{#if item.isRead}
|
|
89
|
+
<span class="text-xs font-light text-gray-400">Read</span>
|
|
90
|
+
{/if}
|
|
91
|
+
<iconify-icon
|
|
92
|
+
icon={item.isRead ? 'ri:check-double-line' : 'uim:check'}
|
|
93
|
+
class={item.isRead ? 'text-blue-700' : 'text-gray-500'}
|
|
94
|
+
style="font-size: 18px;"
|
|
95
|
+
></iconify-icon>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
</DropdownItem>
|
|
100
|
+
{/each}
|
|
101
|
+
{:else}
|
|
102
|
+
<div class="flex h-32 w-80 items-center justify-center space-x-4">
|
|
103
|
+
<p>No Notifications</p>
|
|
104
|
+
</div>
|
|
105
|
+
{/if}
|
|
106
|
+
</div>
|
|
107
|
+
{#if footer}
|
|
108
|
+
{@render footer()}
|
|
109
|
+
{:else}
|
|
110
|
+
<div
|
|
111
|
+
class="-my-1 block bg-gray-50 py-2 text-center text-sm font-medium text-gray-900 hover:bg-gray-100 dark:bg-gray-800 dark:text-white dark:hover:bg-gray-700"
|
|
112
|
+
>
|
|
113
|
+
{#if data.length}
|
|
114
|
+
<button class="w-full" onclick={onClearNotifications}>
|
|
115
|
+
<div class="inline-flex items-center gap-2">
|
|
116
|
+
<iconify-icon icon="ic:round-close"></iconify-icon>
|
|
117
|
+
Clear all
|
|
118
|
+
</div>
|
|
119
|
+
</button>
|
|
120
|
+
{/if}
|
|
121
|
+
</div>
|
|
122
|
+
{/if}
|
|
123
|
+
</Dropdown>
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { PageLoaderProps } from '../../index.js';
|
|
3
|
-
import IconifyIcon from '../icons/IconifyIcon.svelte';
|
|
4
|
-
|
|
5
|
-
let { size = 70, iconColor = 'text-blue-400' }: PageLoaderProps = $props();
|
|
6
|
-
</script>
|
|
7
|
-
|
|
8
|
-
<div class="grid h-full w-full items-center justify-center">
|
|
9
|
-
<IconifyIcon
|
|
10
|
-
class={iconColor}
|
|
11
|
-
icon="svg-spinners:blocks-shuffle-3"
|
|
12
|
-
style="font-size: {size}px;"
|
|
13
|
-
/>
|
|
14
|
-
</div>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { PageLoaderProps } from '../../index.js';
|
|
3
|
+
import IconifyIcon from '../icons/IconifyIcon.svelte';
|
|
4
|
+
|
|
5
|
+
let { size = 70, iconColor = 'text-blue-400' }: PageLoaderProps = $props();
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<div class="grid h-full w-full items-center justify-center">
|
|
9
|
+
<IconifyIcon
|
|
10
|
+
class={iconColor}
|
|
11
|
+
icon="svg-spinners:blocks-shuffle-3"
|
|
12
|
+
style="font-size: {size}px;"
|
|
13
|
+
/>
|
|
14
|
+
</div>
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
|
|
5
|
+
interface PageLoader2Props extends HTMLAttributes<HTMLDivElement> {
|
|
6
|
+
/** Optional message below the spinner */
|
|
7
|
+
message?: string;
|
|
8
|
+
/** Use full-screen overlay (fixed, centered, dimmed background) */
|
|
9
|
+
fullScreen?: boolean;
|
|
10
|
+
/** Loader size in pixels */
|
|
11
|
+
size?: number;
|
|
12
|
+
/** Overlay background classes when fullScreen is true */
|
|
13
|
+
overlayColor?: string;
|
|
14
|
+
/** Static outer ring border color class */
|
|
15
|
+
ringBaseColor?: string;
|
|
16
|
+
/** Rotating outer ring accent classes */
|
|
17
|
+
ringOuterColor?: string;
|
|
18
|
+
/** Rotating inner ring accent classes */
|
|
19
|
+
ringInnerColor?: string;
|
|
20
|
+
/** Center dot and bounce dots color class */
|
|
21
|
+
dotColor?: string;
|
|
22
|
+
/** Message text color class */
|
|
23
|
+
textColor?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let {
|
|
27
|
+
message,
|
|
28
|
+
fullScreen = true,
|
|
29
|
+
size = 56,
|
|
30
|
+
overlayColor = 'bg-background/80',
|
|
31
|
+
ringBaseColor = 'border-muted',
|
|
32
|
+
ringOuterColor = 'border-t-accent border-r-accent/60',
|
|
33
|
+
ringInnerColor = 'border-b-primary border-l-primary/40',
|
|
34
|
+
dotColor = 'bg-accent',
|
|
35
|
+
textColor = 'text-muted-foreground',
|
|
36
|
+
class: className,
|
|
37
|
+
...restProps
|
|
38
|
+
}: PageLoader2Props = $props();
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<div
|
|
42
|
+
{...restProps}
|
|
43
|
+
class={clsx(
|
|
44
|
+
'flex flex-col items-center justify-center gap-6',
|
|
45
|
+
fullScreen && ['fixed inset-0 z-50 backdrop-blur-sm', overlayColor],
|
|
46
|
+
className
|
|
47
|
+
)}
|
|
48
|
+
role="status"
|
|
49
|
+
aria-live="polite"
|
|
50
|
+
aria-label={message ?? 'Loading'}
|
|
51
|
+
>
|
|
52
|
+
<div class="relative" style={`width: ${size}px; height: ${size}px;`} aria-hidden="true">
|
|
53
|
+
<div class={clsx('absolute inset-0 rounded-full border-2', ringBaseColor)}></div>
|
|
54
|
+
<div
|
|
55
|
+
class={clsx(
|
|
56
|
+
'absolute inset-0 rounded-full border-2 border-transparent animate-[spin_0.8s_linear_infinite]',
|
|
57
|
+
ringOuterColor
|
|
58
|
+
)}
|
|
59
|
+
></div>
|
|
60
|
+
<div
|
|
61
|
+
class={clsx(
|
|
62
|
+
'absolute inset-1 rounded-full border-2 border-transparent animate-[spin_1.2s_linear_infinite_reverse]',
|
|
63
|
+
ringInnerColor
|
|
64
|
+
)}
|
|
65
|
+
></div>
|
|
66
|
+
<div class="absolute inset-0 flex items-center justify-center">
|
|
67
|
+
<div class={clsx('h-2 w-2 rounded-full animate-pulse', dotColor)}></div>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
{#if message}
|
|
72
|
+
<div class="flex flex-col items-center gap-2">
|
|
73
|
+
<p class={clsx('text-sm font-medium', textColor)}>{message}</p>
|
|
74
|
+
<div class="flex gap-1.5" aria-hidden="true">
|
|
75
|
+
<span
|
|
76
|
+
class={clsx(
|
|
77
|
+
'h-1.5 w-1.5 rounded-full animate-[page-loader-bounce_1.4s_ease-in-out_infinite_both]',
|
|
78
|
+
dotColor
|
|
79
|
+
)}
|
|
80
|
+
style="animation-delay: 0ms;"
|
|
81
|
+
></span>
|
|
82
|
+
<span
|
|
83
|
+
class={clsx(
|
|
84
|
+
'h-1.5 w-1.5 rounded-full animate-[page-loader-bounce_1.4s_ease-in-out_infinite_both]',
|
|
85
|
+
dotColor
|
|
86
|
+
)}
|
|
87
|
+
style="animation-delay: 160ms;"
|
|
88
|
+
></span>
|
|
89
|
+
<span
|
|
90
|
+
class={clsx(
|
|
91
|
+
'h-1.5 w-1.5 rounded-full animate-[page-loader-bounce_1.4s_ease-in-out_infinite_both]',
|
|
92
|
+
dotColor
|
|
93
|
+
)}
|
|
94
|
+
style="animation-delay: 320ms;"
|
|
95
|
+
></span>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
{/if}
|
|
99
|
+
</div>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
interface PageLoader2Props extends HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
/** Optional message below the spinner */
|
|
4
|
+
message?: string;
|
|
5
|
+
/** Use full-screen overlay (fixed, centered, dimmed background) */
|
|
6
|
+
fullScreen?: boolean;
|
|
7
|
+
/** Loader size in pixels */
|
|
8
|
+
size?: number;
|
|
9
|
+
/** Overlay background classes when fullScreen is true */
|
|
10
|
+
overlayColor?: string;
|
|
11
|
+
/** Static outer ring border color class */
|
|
12
|
+
ringBaseColor?: string;
|
|
13
|
+
/** Rotating outer ring accent classes */
|
|
14
|
+
ringOuterColor?: string;
|
|
15
|
+
/** Rotating inner ring accent classes */
|
|
16
|
+
ringInnerColor?: string;
|
|
17
|
+
/** Center dot and bounce dots color class */
|
|
18
|
+
dotColor?: string;
|
|
19
|
+
/** Message text color class */
|
|
20
|
+
textColor?: string;
|
|
21
|
+
}
|
|
22
|
+
declare const PageLoader2: import("svelte").Component<PageLoader2Props, {}, "">;
|
|
23
|
+
type PageLoader2 = ReturnType<typeof PageLoader2>;
|
|
24
|
+
export default PageLoader2;
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { default as PageLoader } from
|
|
1
|
+
export { default as PageLoader } from './PageLoader.svelte';
|
|
2
|
+
export { default as PageLoader2 } from './PageLoader2.svelte';
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { default as PageLoader } from
|
|
1
|
+
export { default as PageLoader } from './PageLoader.svelte';
|
|
2
|
+
export { default as PageLoader2 } from './PageLoader2.svelte';
|
|
@@ -1,96 +1,96 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { Dropdown, type PaginateProps } from '../../index.js';
|
|
3
|
-
|
|
4
|
-
let {
|
|
5
|
-
currentPage,
|
|
6
|
-
hasNextPage,
|
|
7
|
-
hasPreviousPage,
|
|
8
|
-
onNextPage,
|
|
9
|
-
onPreviousPage,
|
|
10
|
-
refresh = null,
|
|
11
|
-
totalPages,
|
|
12
|
-
hiddenColumns = $bindable([]),
|
|
13
|
-
tableColumns = [],
|
|
14
|
-
textSmall = false,
|
|
15
|
-
hideLabel = true,
|
|
16
|
-
recordCount = 0
|
|
17
|
-
}: PaginateProps = $props();
|
|
18
|
-
|
|
19
|
-
// let hideState = tableColumns.map(x => )
|
|
20
|
-
let hideState = $state<Record<string, boolean>>({});
|
|
21
|
-
hiddenColumns.forEach((x) => (hideState[x] = true));
|
|
22
|
-
// $: hiddenColumns = Object.keys(hideState).filter((x) => hideState[x]);
|
|
23
|
-
// let hiddenColumns
|
|
24
|
-
|
|
25
|
-
let open = $state(false);
|
|
26
|
-
</script>
|
|
27
|
-
|
|
28
|
-
<div class:text-sm={textSmall} class="flex w-full items-center justify-between gap-2 text-gray-600">
|
|
29
|
-
<button
|
|
30
|
-
class=" items-center justify-center gap-1 p-2 text-sm font-semibold"
|
|
31
|
-
class:hidden={!totalPages}
|
|
32
|
-
class:flex={totalPages}
|
|
33
|
-
onclick={onPreviousPage}
|
|
34
|
-
disabled={!hasPreviousPage}
|
|
35
|
-
class:active={hasPreviousPage}
|
|
36
|
-
class:hover:bg-gray-200={hasPreviousPage}
|
|
37
|
-
class:rounded-md={hasPreviousPage}
|
|
38
|
-
class:text-gray-300={!hasPreviousPage}
|
|
39
|
-
>
|
|
40
|
-
<iconify-icon icon="material-symbols:arrow-back" style="font-size: 18px"></iconify-icon>
|
|
41
|
-
{#if !hideLabel}
|
|
42
|
-
<span>PREV</span>
|
|
43
|
-
{/if}
|
|
44
|
-
</button>
|
|
45
|
-
<div class="text-sm font-semibold">
|
|
46
|
-
{#if !hideLabel}
|
|
47
|
-
<span>Page</span>
|
|
48
|
-
{/if}
|
|
49
|
-
<span class:hidden={!totalPages} class:flex={totalPages}>{currentPage}/{totalPages}</span>
|
|
50
|
-
</div>
|
|
51
|
-
<span class:hidden={!recordCount} class:flex={recordCount}>({recordCount})</span>
|
|
52
|
-
|
|
53
|
-
<button
|
|
54
|
-
class="flex items-center justify-center gap-1 p-2 text-sm font-semibold"
|
|
55
|
-
class:hidden={!totalPages}
|
|
56
|
-
class:flex={totalPages}
|
|
57
|
-
onclick={onNextPage}
|
|
58
|
-
disabled={!hasNextPage}
|
|
59
|
-
class:active={hasNextPage}
|
|
60
|
-
class:hover:bg-gray-200={hasNextPage}
|
|
61
|
-
class:rounded-md={hasNextPage}
|
|
62
|
-
class:text-gray-300={!hasNextPage}
|
|
63
|
-
>
|
|
64
|
-
{#if !hideLabel}
|
|
65
|
-
<span>NEXT</span>
|
|
66
|
-
{/if}
|
|
67
|
-
<iconify-icon icon="material-symbols:arrow-forward" style="font-size: 18px"></iconify-icon>
|
|
68
|
-
</button>
|
|
69
|
-
<button
|
|
70
|
-
type="button"
|
|
71
|
-
aria-label="arrows-clockwise"
|
|
72
|
-
class="rotate-2 font-bold hover:text-gray-600"
|
|
73
|
-
class:hidden={!refresh}
|
|
74
|
-
onclick={refresh}
|
|
75
|
-
>
|
|
76
|
-
<iconify-icon icon="ph:arrows-clockwise" class="hover:animate-spin hover:text-gray-400"
|
|
77
|
-
></iconify-icon>
|
|
78
|
-
</button>
|
|
79
|
-
<div class:hidden={!tableColumns.length} class:flex={tableColumns}>
|
|
80
|
-
<button onclick={() => (open = !open)}>
|
|
81
|
-
<iconify-icon icon="ph:columns" class="text-red-500 hover:text-red-800"></iconify-icon>
|
|
82
|
-
<!-- <Tooltip>Toggle Columns</Tooltip> -->
|
|
83
|
-
</button>
|
|
84
|
-
<Dropdown
|
|
85
|
-
bind:isOpen={open}
|
|
86
|
-
class="scrollbar-thumb-blue scrollbar-thumb-rounded scrollbar-track-blue-lighter scrollbar-w-2 scrolling-touch h-56 min-w-40 overflow-y-auto px-3 pb-3 text-sm"
|
|
87
|
-
>
|
|
88
|
-
{#each tableColumns as column}
|
|
89
|
-
<li class="flex w-full px-2 py-1.5 whitespace-nowrap">
|
|
90
|
-
<!-- <Toggle bind:checked={hideState[column.id]} class="cursor-pointer" /> -->
|
|
91
|
-
{column.header}
|
|
92
|
-
</li>
|
|
93
|
-
{/each}
|
|
94
|
-
</Dropdown>
|
|
95
|
-
</div>
|
|
96
|
-
</div>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Dropdown, type PaginateProps } from '../../index.js';
|
|
3
|
+
|
|
4
|
+
let {
|
|
5
|
+
currentPage,
|
|
6
|
+
hasNextPage,
|
|
7
|
+
hasPreviousPage,
|
|
8
|
+
onNextPage,
|
|
9
|
+
onPreviousPage,
|
|
10
|
+
refresh = null,
|
|
11
|
+
totalPages,
|
|
12
|
+
hiddenColumns = $bindable([]),
|
|
13
|
+
tableColumns = [],
|
|
14
|
+
textSmall = false,
|
|
15
|
+
hideLabel = true,
|
|
16
|
+
recordCount = 0
|
|
17
|
+
}: PaginateProps = $props();
|
|
18
|
+
|
|
19
|
+
// let hideState = tableColumns.map(x => )
|
|
20
|
+
let hideState = $state<Record<string, boolean>>({});
|
|
21
|
+
hiddenColumns.forEach((x) => (hideState[x] = true));
|
|
22
|
+
// $: hiddenColumns = Object.keys(hideState).filter((x) => hideState[x]);
|
|
23
|
+
// let hiddenColumns
|
|
24
|
+
|
|
25
|
+
let open = $state(false);
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<div class:text-sm={textSmall} class="flex w-full items-center justify-between gap-2 text-gray-600">
|
|
29
|
+
<button
|
|
30
|
+
class=" items-center justify-center gap-1 p-2 text-sm font-semibold"
|
|
31
|
+
class:hidden={!totalPages}
|
|
32
|
+
class:flex={totalPages}
|
|
33
|
+
onclick={onPreviousPage}
|
|
34
|
+
disabled={!hasPreviousPage}
|
|
35
|
+
class:active={hasPreviousPage}
|
|
36
|
+
class:hover:bg-gray-200={hasPreviousPage}
|
|
37
|
+
class:rounded-md={hasPreviousPage}
|
|
38
|
+
class:text-gray-300={!hasPreviousPage}
|
|
39
|
+
>
|
|
40
|
+
<iconify-icon icon="material-symbols:arrow-back" style="font-size: 18px"></iconify-icon>
|
|
41
|
+
{#if !hideLabel}
|
|
42
|
+
<span>PREV</span>
|
|
43
|
+
{/if}
|
|
44
|
+
</button>
|
|
45
|
+
<div class="text-sm font-semibold">
|
|
46
|
+
{#if !hideLabel}
|
|
47
|
+
<span>Page</span>
|
|
48
|
+
{/if}
|
|
49
|
+
<span class:hidden={!totalPages} class:flex={totalPages}>{currentPage}/{totalPages}</span>
|
|
50
|
+
</div>
|
|
51
|
+
<span class:hidden={!recordCount} class:flex={recordCount}>({recordCount})</span>
|
|
52
|
+
|
|
53
|
+
<button
|
|
54
|
+
class="flex items-center justify-center gap-1 p-2 text-sm font-semibold"
|
|
55
|
+
class:hidden={!totalPages}
|
|
56
|
+
class:flex={totalPages}
|
|
57
|
+
onclick={onNextPage}
|
|
58
|
+
disabled={!hasNextPage}
|
|
59
|
+
class:active={hasNextPage}
|
|
60
|
+
class:hover:bg-gray-200={hasNextPage}
|
|
61
|
+
class:rounded-md={hasNextPage}
|
|
62
|
+
class:text-gray-300={!hasNextPage}
|
|
63
|
+
>
|
|
64
|
+
{#if !hideLabel}
|
|
65
|
+
<span>NEXT</span>
|
|
66
|
+
{/if}
|
|
67
|
+
<iconify-icon icon="material-symbols:arrow-forward" style="font-size: 18px"></iconify-icon>
|
|
68
|
+
</button>
|
|
69
|
+
<button
|
|
70
|
+
type="button"
|
|
71
|
+
aria-label="arrows-clockwise"
|
|
72
|
+
class="rotate-2 font-bold hover:text-gray-600"
|
|
73
|
+
class:hidden={!refresh}
|
|
74
|
+
onclick={refresh}
|
|
75
|
+
>
|
|
76
|
+
<iconify-icon icon="ph:arrows-clockwise" class="hover:animate-spin hover:text-gray-400"
|
|
77
|
+
></iconify-icon>
|
|
78
|
+
</button>
|
|
79
|
+
<div class:hidden={!tableColumns.length} class:flex={tableColumns}>
|
|
80
|
+
<button onclick={() => (open = !open)}>
|
|
81
|
+
<iconify-icon icon="ph:columns" class="text-red-500 hover:text-red-800"></iconify-icon>
|
|
82
|
+
<!-- <Tooltip>Toggle Columns</Tooltip> -->
|
|
83
|
+
</button>
|
|
84
|
+
<Dropdown
|
|
85
|
+
bind:isOpen={open}
|
|
86
|
+
class="scrollbar-thumb-blue scrollbar-thumb-rounded scrollbar-track-blue-lighter scrollbar-w-2 scrolling-touch h-56 min-w-40 overflow-y-auto px-3 pb-3 text-sm"
|
|
87
|
+
>
|
|
88
|
+
{#each tableColumns as column}
|
|
89
|
+
<li class="flex w-full px-2 py-1.5 whitespace-nowrap">
|
|
90
|
+
<!-- <Toggle bind:checked={hideState[column.id]} class="cursor-pointer" /> -->
|
|
91
|
+
{column.header}
|
|
92
|
+
</li>
|
|
93
|
+
{/each}
|
|
94
|
+
</Dropdown>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|