@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,85 +1,85 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
let mappers: ((name: string) => ConstructorOfATypedSvelteComponent)[] = [];
|
|
3
|
-
function componentNameToType(name: string) {
|
|
4
|
-
for (let i = 0; i < mappers.length; i++) {
|
|
5
|
-
let cmp = mappers[i](name);
|
|
6
|
-
if (cmp != null) return cmp;
|
|
7
|
-
}
|
|
8
|
-
return null;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function addMapper(f: (name: string) => ConstructorOfATypedSvelteComponent) {
|
|
12
|
-
mappers = [f, ...mappers];
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function removeMapper(f: (name: string) => ConstructorOfATypedSvelteComponent) {
|
|
16
|
-
mappers = mappers.filter((x) => x != f);
|
|
17
|
-
}
|
|
18
|
-
</script>
|
|
19
|
-
|
|
20
|
-
<script lang="ts">
|
|
21
|
-
import {
|
|
22
|
-
IconifyIcon,
|
|
23
|
-
type IComponentDescriptor,
|
|
24
|
-
type IDocumentRendererProps
|
|
25
|
-
} from '../../index.js';
|
|
26
|
-
|
|
27
|
-
let {
|
|
28
|
-
descriptor,
|
|
29
|
-
showTitle = true,
|
|
30
|
-
contextKey,
|
|
31
|
-
toggleCollapse,
|
|
32
|
-
close
|
|
33
|
-
}: IDocumentRendererProps = $props();
|
|
34
|
-
|
|
35
|
-
function decode(descriptor: IComponentDescriptor) {
|
|
36
|
-
return {
|
|
37
|
-
compoent: componentNameToType(descriptor.type),
|
|
38
|
-
props: descriptor.props || {}
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
let data = $derived(decode(descriptor));
|
|
43
|
-
</script>
|
|
44
|
-
|
|
45
|
-
{#if data.compoent}
|
|
46
|
-
<div class="flex-grow">
|
|
47
|
-
{#if descriptor.title && showTitle}
|
|
48
|
-
<div class="flex items-center justify-between border-b border-dotted pb-1">
|
|
49
|
-
<h3 class="font-bold text-teal-500">
|
|
50
|
-
{descriptor.title || ''}
|
|
51
|
-
</h3>
|
|
52
|
-
<div class="flex items-center gap-2">
|
|
53
|
-
<button
|
|
54
|
-
aria-label="collapse"
|
|
55
|
-
onclick={(_) => toggleCollapse(descriptor.id!)}
|
|
56
|
-
class="grid place-content-center rounded-full p-1 hover:bg-gray-200"
|
|
57
|
-
class:hidden={!descriptor.collapsible}
|
|
58
|
-
>
|
|
59
|
-
<IconifyIcon
|
|
60
|
-
icon={descriptor.collapsed
|
|
61
|
-
? 'iconamoon:arrow-down-2-duotone'
|
|
62
|
-
: 'iconamoon:arrow-up-2-duotone'}
|
|
63
|
-
style="font-size: 20px;"
|
|
64
|
-
/>
|
|
65
|
-
</button>
|
|
66
|
-
<button
|
|
67
|
-
aria-label="close"
|
|
68
|
-
onclick={(e) => close({ id: descriptor.id!, data: e.detail })}
|
|
69
|
-
class="grid place-content-center rounded-full p-1 hover:bg-red-200 hover:text-red-400"
|
|
70
|
-
class:hidden={!descriptor.closable}
|
|
71
|
-
>
|
|
72
|
-
<iconify-icon icon="ic:round-close" style="font-size: 20px;"></iconify-icon>
|
|
73
|
-
</button>
|
|
74
|
-
</div>
|
|
75
|
-
</div>
|
|
76
|
-
{/if}
|
|
77
|
-
<div class:hidden={descriptor.collapsed}>
|
|
78
|
-
<data.compoent
|
|
79
|
-
{...data.props}
|
|
80
|
-
{contextKey}
|
|
81
|
-
close={(e: any) => close({ id: descriptor.id!, data: e.detail })}
|
|
82
|
-
/>
|
|
83
|
-
</div>
|
|
84
|
-
</div>
|
|
85
|
-
{/if}
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
let mappers: ((name: string) => ConstructorOfATypedSvelteComponent)[] = [];
|
|
3
|
+
function componentNameToType(name: string) {
|
|
4
|
+
for (let i = 0; i < mappers.length; i++) {
|
|
5
|
+
let cmp = mappers[i](name);
|
|
6
|
+
if (cmp != null) return cmp;
|
|
7
|
+
}
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function addMapper(f: (name: string) => ConstructorOfATypedSvelteComponent) {
|
|
12
|
+
mappers = [f, ...mappers];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function removeMapper(f: (name: string) => ConstructorOfATypedSvelteComponent) {
|
|
16
|
+
mappers = mappers.filter((x) => x != f);
|
|
17
|
+
}
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<script lang="ts">
|
|
21
|
+
import {
|
|
22
|
+
IconifyIcon,
|
|
23
|
+
type IComponentDescriptor,
|
|
24
|
+
type IDocumentRendererProps
|
|
25
|
+
} from '../../index.js';
|
|
26
|
+
|
|
27
|
+
let {
|
|
28
|
+
descriptor,
|
|
29
|
+
showTitle = true,
|
|
30
|
+
contextKey,
|
|
31
|
+
toggleCollapse,
|
|
32
|
+
close
|
|
33
|
+
}: IDocumentRendererProps = $props();
|
|
34
|
+
|
|
35
|
+
function decode(descriptor: IComponentDescriptor) {
|
|
36
|
+
return {
|
|
37
|
+
compoent: componentNameToType(descriptor.type),
|
|
38
|
+
props: descriptor.props || {}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let data = $derived(decode(descriptor));
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
{#if data.compoent}
|
|
46
|
+
<div class="flex-grow">
|
|
47
|
+
{#if descriptor.title && showTitle}
|
|
48
|
+
<div class="flex items-center justify-between border-b border-dotted pb-1">
|
|
49
|
+
<h3 class="font-bold text-teal-500">
|
|
50
|
+
{descriptor.title || ''}
|
|
51
|
+
</h3>
|
|
52
|
+
<div class="flex items-center gap-2">
|
|
53
|
+
<button
|
|
54
|
+
aria-label="collapse"
|
|
55
|
+
onclick={(_) => toggleCollapse(descriptor.id!)}
|
|
56
|
+
class="grid place-content-center rounded-full p-1 hover:bg-gray-200"
|
|
57
|
+
class:hidden={!descriptor.collapsible}
|
|
58
|
+
>
|
|
59
|
+
<IconifyIcon
|
|
60
|
+
icon={descriptor.collapsed
|
|
61
|
+
? 'iconamoon:arrow-down-2-duotone'
|
|
62
|
+
: 'iconamoon:arrow-up-2-duotone'}
|
|
63
|
+
style="font-size: 20px;"
|
|
64
|
+
/>
|
|
65
|
+
</button>
|
|
66
|
+
<button
|
|
67
|
+
aria-label="close"
|
|
68
|
+
onclick={(e) => close({ id: descriptor.id!, data: e.detail })}
|
|
69
|
+
class="grid place-content-center rounded-full p-1 hover:bg-red-200 hover:text-red-400"
|
|
70
|
+
class:hidden={!descriptor.closable}
|
|
71
|
+
>
|
|
72
|
+
<iconify-icon icon="ic:round-close" style="font-size: 20px;"></iconify-icon>
|
|
73
|
+
</button>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
{/if}
|
|
77
|
+
<div class:hidden={descriptor.collapsed}>
|
|
78
|
+
<data.compoent
|
|
79
|
+
{...data.props}
|
|
80
|
+
{contextKey}
|
|
81
|
+
close={(e: any) => close({ id: descriptor.id!, data: e.detail })}
|
|
82
|
+
/>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
{/if}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
import type { Snippet } from 'svelte';
|
|
3
|
-
|
|
4
|
-
export interface TFContentWrapperProps {
|
|
5
|
-
topBar?: Snippet;
|
|
6
|
-
children: any;
|
|
7
|
-
}
|
|
8
|
-
</script>
|
|
9
|
-
|
|
10
|
-
<script lang="ts">
|
|
11
|
-
let { topBar, children }: TFContentWrapperProps = $props();
|
|
12
|
-
</script>
|
|
13
|
-
|
|
14
|
-
<section id="tf-content" class="flex h-full w-full flex-col">
|
|
15
|
-
<div>
|
|
16
|
-
{@render topBar?.()}
|
|
17
|
-
</div>
|
|
18
|
-
<section class="flex h-full w-full flex-grow rounded-tl-lg bg-[#f4f3ef]">
|
|
19
|
-
{@render children()}
|
|
20
|
-
</section>
|
|
21
|
-
</section>
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
export interface TFContentWrapperProps {
|
|
5
|
+
topBar?: Snippet;
|
|
6
|
+
children: any;
|
|
7
|
+
}
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<script lang="ts">
|
|
11
|
+
let { topBar, children }: TFContentWrapperProps = $props();
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<section id="tf-content" class="flex h-full w-full flex-col">
|
|
15
|
+
<div>
|
|
16
|
+
{@render topBar?.()}
|
|
17
|
+
</div>
|
|
18
|
+
<section class="flex h-full w-full flex-grow rounded-tl-lg bg-[#f4f3ef]">
|
|
19
|
+
{@render children()}
|
|
20
|
+
</section>
|
|
21
|
+
</section>
|
|
@@ -1,166 +1,166 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
interface UserData {
|
|
3
|
-
firstName?: string;
|
|
4
|
-
lastName?: string;
|
|
5
|
-
fullName?: string;
|
|
6
|
-
role?: string;
|
|
7
|
-
username?: string;
|
|
8
|
-
initials?: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface TFHeaderProps {
|
|
12
|
-
user?: UserData;
|
|
13
|
-
hideSidebar?: boolean;
|
|
14
|
-
title?: string;
|
|
15
|
-
onsignout?: () => void;
|
|
16
|
-
notificationCount?: number;
|
|
17
|
-
showNotifications?: boolean;
|
|
18
|
-
// readNotifications?: () => Promise<any[]> | any[];
|
|
19
|
-
notificationList?: Snippet;
|
|
20
|
-
rightSideComponent?: Snippet;
|
|
21
|
-
leftSideComponent?: Snippet;
|
|
22
|
-
}
|
|
23
|
-
</script>
|
|
24
|
-
|
|
25
|
-
<script lang="ts">
|
|
26
|
-
import { Avatar } from '../../../ui/avatar/index.js';
|
|
27
|
-
import Button from '../../../ui/buttons/Button.svelte';
|
|
28
|
-
import { slide } from 'svelte/transition';
|
|
29
|
-
|
|
30
|
-
import { clickOutsideAction } from '../../../utils/svelte-legos.js';
|
|
31
|
-
import { DropdownDivider } from '../../../ui/dropdown/index.js';
|
|
32
|
-
import { Indicator } from '../../../ui/indicator/index.js';
|
|
33
|
-
// import NotificationList from '../../../ui/notificationList/NotificationList.svelte';
|
|
34
|
-
import type { Snippet } from 'svelte';
|
|
35
|
-
let {
|
|
36
|
-
user,
|
|
37
|
-
hideSidebar = $bindable(false),
|
|
38
|
-
title,
|
|
39
|
-
onsignout,
|
|
40
|
-
notificationCount = 0,
|
|
41
|
-
showNotifications = true,
|
|
42
|
-
notificationList,
|
|
43
|
-
rightSideComponent,
|
|
44
|
-
leftSideComponent
|
|
45
|
-
}: TFHeaderProps = $props();
|
|
46
|
-
let showUser = $state(false);
|
|
47
|
-
let openNotification = $state(false);
|
|
48
|
-
</script>
|
|
49
|
-
|
|
50
|
-
<nav class="flex items-center">
|
|
51
|
-
<button
|
|
52
|
-
class="grid place-content-center rounded-full p-2 hover:bg-gray-200"
|
|
53
|
-
onclick={() => (hideSidebar = !hideSidebar)}
|
|
54
|
-
aria-label="toggle"
|
|
55
|
-
>
|
|
56
|
-
<iconify-icon
|
|
57
|
-
icon={hideSidebar ? 'mdi:menu-close' : 'ic:round-menu-open'}
|
|
58
|
-
style="font-size: 20px;"
|
|
59
|
-
></iconify-icon>
|
|
60
|
-
</button>
|
|
61
|
-
<div class="hidden flex-grow items-center gap-4 sm:flex">
|
|
62
|
-
<div class="font-semibold text-teal-800">
|
|
63
|
-
{title}
|
|
64
|
-
</div>
|
|
65
|
-
</div>
|
|
66
|
-
{@render leftSideComponent?.()}
|
|
67
|
-
<div class="flex flex-grow sm:hidden"></div>
|
|
68
|
-
{@render rightSideComponent?.()}
|
|
69
|
-
|
|
70
|
-
{#if showNotifications}
|
|
71
|
-
<div
|
|
72
|
-
class="flex items-center gap-4"
|
|
73
|
-
use:clickOutsideAction
|
|
74
|
-
onclickoutside={() => (openNotification = false)}
|
|
75
|
-
>
|
|
76
|
-
<button
|
|
77
|
-
class="notifications relative grid cursor-pointer place-content-center hover:text-teal-400"
|
|
78
|
-
use:clickOutsideAction
|
|
79
|
-
onclick={() => (openNotification = !openNotification)}
|
|
80
|
-
>
|
|
81
|
-
<iconify-icon icon="charm:bell" class="blue-red-600 text-2xl"></iconify-icon>
|
|
82
|
-
<Indicator
|
|
83
|
-
color="red"
|
|
84
|
-
border
|
|
85
|
-
size="xl"
|
|
86
|
-
placement="top-right"
|
|
87
|
-
class="font- text-xs text-white {!notificationCount && 'hidden'}"
|
|
88
|
-
>{notificationCount && notificationCount > 10 ? '10+' : notificationCount}</Indicator
|
|
89
|
-
>
|
|
90
|
-
</button>
|
|
91
|
-
|
|
92
|
-
{@render notificationList?.()}
|
|
93
|
-
</div>
|
|
94
|
-
{/if}
|
|
95
|
-
|
|
96
|
-
<div class="flex items-center gap-4">
|
|
97
|
-
<div
|
|
98
|
-
class="user grid place-content-center"
|
|
99
|
-
use:clickOutsideAction
|
|
100
|
-
onclickoutside={() => (showUser = false)}
|
|
101
|
-
>
|
|
102
|
-
<Button
|
|
103
|
-
color="light"
|
|
104
|
-
pill
|
|
105
|
-
class="h-10 max-w-[150px] border-gray-300 !p-0 sm:!p-1"
|
|
106
|
-
ripple={false}
|
|
107
|
-
onclick={() => (showUser = !showUser)}
|
|
108
|
-
>
|
|
109
|
-
<Avatar class="h-9 w-9 bg-sky-300 text-sm sm:mr-2">
|
|
110
|
-
{user?.initials}
|
|
111
|
-
</Avatar>
|
|
112
|
-
<div class="hidden text-left text-xs sm:block sm:pr-2">
|
|
113
|
-
<div class="w-20 truncate">
|
|
114
|
-
<span class="font-semibold text-black">{user?.firstName}</span>
|
|
115
|
-
</div>
|
|
116
|
-
{#if user?.role}
|
|
117
|
-
<div class="w-20 truncate text-gray-500">
|
|
118
|
-
<span>{user.role}</span>
|
|
119
|
-
</div>
|
|
120
|
-
{:else}
|
|
121
|
-
<p class="flex w-20 truncate text-gray-500">{user?.username}</p>
|
|
122
|
-
{/if}
|
|
123
|
-
</div>
|
|
124
|
-
</Button>
|
|
125
|
-
{#if showUser}
|
|
126
|
-
<div class="relative">
|
|
127
|
-
<div
|
|
128
|
-
class="absolute right-0 z-10 mt-2 rounded-md bg-white
|
|
129
|
-
py-2 shadow-md shadow-gray-300
|
|
130
|
-
"
|
|
131
|
-
transition:slide
|
|
132
|
-
use:clickOutsideAction
|
|
133
|
-
>
|
|
134
|
-
<div class="space-y-2 px-4 py-2">
|
|
135
|
-
<span class="block truncate text-sm font-bold">{user?.fullName}</span>
|
|
136
|
-
<div class="block truncate text-sm">
|
|
137
|
-
<span class="font-light text-gray-500">Role:</span>
|
|
138
|
-
<span class="font-bold">{user?.role}</span>
|
|
139
|
-
</div>
|
|
140
|
-
<div class="block truncate text-sm">
|
|
141
|
-
<span class="font-light text-gray-500">Username:</span>
|
|
142
|
-
<span class="font-bold">{user?.username}</span>
|
|
143
|
-
</div>
|
|
144
|
-
</div>
|
|
145
|
-
<DropdownDivider />
|
|
146
|
-
<div class="grid">
|
|
147
|
-
<Button
|
|
148
|
-
ripple={false}
|
|
149
|
-
class="mx-0.5 flex justify-start gap-1 border bg-red-50 text-red-600 hover:bg-red-100"
|
|
150
|
-
onclick={() => {
|
|
151
|
-
showUser = false;
|
|
152
|
-
onsignout?.();
|
|
153
|
-
}}
|
|
154
|
-
>
|
|
155
|
-
{#snippet leadingIcon()}
|
|
156
|
-
<iconify-icon icon="stash:signout" style="font-size: 20px;"></iconify-icon>
|
|
157
|
-
{/snippet}
|
|
158
|
-
Sign Out
|
|
159
|
-
</Button>
|
|
160
|
-
</div>
|
|
161
|
-
</div>
|
|
162
|
-
</div>
|
|
163
|
-
{/if}
|
|
164
|
-
</div>
|
|
165
|
-
</div>
|
|
166
|
-
</nav>
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
interface UserData {
|
|
3
|
+
firstName?: string;
|
|
4
|
+
lastName?: string;
|
|
5
|
+
fullName?: string;
|
|
6
|
+
role?: string;
|
|
7
|
+
username?: string;
|
|
8
|
+
initials?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface TFHeaderProps {
|
|
12
|
+
user?: UserData;
|
|
13
|
+
hideSidebar?: boolean;
|
|
14
|
+
title?: string;
|
|
15
|
+
onsignout?: () => void;
|
|
16
|
+
notificationCount?: number;
|
|
17
|
+
showNotifications?: boolean;
|
|
18
|
+
// readNotifications?: () => Promise<any[]> | any[];
|
|
19
|
+
notificationList?: Snippet;
|
|
20
|
+
rightSideComponent?: Snippet;
|
|
21
|
+
leftSideComponent?: Snippet;
|
|
22
|
+
}
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<script lang="ts">
|
|
26
|
+
import { Avatar } from '../../../ui/avatar/index.js';
|
|
27
|
+
import Button from '../../../ui/buttons/Button.svelte';
|
|
28
|
+
import { slide } from 'svelte/transition';
|
|
29
|
+
|
|
30
|
+
import { clickOutsideAction } from '../../../utils/svelte-legos.js';
|
|
31
|
+
import { DropdownDivider } from '../../../ui/dropdown/index.js';
|
|
32
|
+
import { Indicator } from '../../../ui/indicator/index.js';
|
|
33
|
+
// import NotificationList from '../../../ui/notificationList/NotificationList.svelte';
|
|
34
|
+
import type { Snippet } from 'svelte';
|
|
35
|
+
let {
|
|
36
|
+
user,
|
|
37
|
+
hideSidebar = $bindable(false),
|
|
38
|
+
title,
|
|
39
|
+
onsignout,
|
|
40
|
+
notificationCount = 0,
|
|
41
|
+
showNotifications = true,
|
|
42
|
+
notificationList,
|
|
43
|
+
rightSideComponent,
|
|
44
|
+
leftSideComponent
|
|
45
|
+
}: TFHeaderProps = $props();
|
|
46
|
+
let showUser = $state(false);
|
|
47
|
+
let openNotification = $state(false);
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<nav class="flex items-center">
|
|
51
|
+
<button
|
|
52
|
+
class="grid place-content-center rounded-full p-2 hover:bg-gray-200"
|
|
53
|
+
onclick={() => (hideSidebar = !hideSidebar)}
|
|
54
|
+
aria-label="toggle"
|
|
55
|
+
>
|
|
56
|
+
<iconify-icon
|
|
57
|
+
icon={hideSidebar ? 'mdi:menu-close' : 'ic:round-menu-open'}
|
|
58
|
+
style="font-size: 20px;"
|
|
59
|
+
></iconify-icon>
|
|
60
|
+
</button>
|
|
61
|
+
<div class="hidden flex-grow items-center gap-4 sm:flex">
|
|
62
|
+
<div class="font-semibold text-teal-800">
|
|
63
|
+
{title}
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
{@render leftSideComponent?.()}
|
|
67
|
+
<div class="flex flex-grow sm:hidden"></div>
|
|
68
|
+
{@render rightSideComponent?.()}
|
|
69
|
+
|
|
70
|
+
{#if showNotifications}
|
|
71
|
+
<div
|
|
72
|
+
class="flex items-center gap-4"
|
|
73
|
+
use:clickOutsideAction
|
|
74
|
+
onclickoutside={() => (openNotification = false)}
|
|
75
|
+
>
|
|
76
|
+
<button
|
|
77
|
+
class="notifications relative grid cursor-pointer place-content-center hover:text-teal-400"
|
|
78
|
+
use:clickOutsideAction
|
|
79
|
+
onclick={() => (openNotification = !openNotification)}
|
|
80
|
+
>
|
|
81
|
+
<iconify-icon icon="charm:bell" class="blue-red-600 text-2xl"></iconify-icon>
|
|
82
|
+
<Indicator
|
|
83
|
+
color="red"
|
|
84
|
+
border
|
|
85
|
+
size="xl"
|
|
86
|
+
placement="top-right"
|
|
87
|
+
class="font- text-xs text-white {!notificationCount && 'hidden'}"
|
|
88
|
+
>{notificationCount && notificationCount > 10 ? '10+' : notificationCount}</Indicator
|
|
89
|
+
>
|
|
90
|
+
</button>
|
|
91
|
+
|
|
92
|
+
{@render notificationList?.()}
|
|
93
|
+
</div>
|
|
94
|
+
{/if}
|
|
95
|
+
|
|
96
|
+
<div class="flex items-center gap-4">
|
|
97
|
+
<div
|
|
98
|
+
class="user grid place-content-center"
|
|
99
|
+
use:clickOutsideAction
|
|
100
|
+
onclickoutside={() => (showUser = false)}
|
|
101
|
+
>
|
|
102
|
+
<Button
|
|
103
|
+
color="light"
|
|
104
|
+
pill
|
|
105
|
+
class="h-10 max-w-[150px] border-gray-300 !p-0 sm:!p-1"
|
|
106
|
+
ripple={false}
|
|
107
|
+
onclick={() => (showUser = !showUser)}
|
|
108
|
+
>
|
|
109
|
+
<Avatar class="h-9 w-9 bg-sky-300 text-sm sm:mr-2">
|
|
110
|
+
{user?.initials}
|
|
111
|
+
</Avatar>
|
|
112
|
+
<div class="hidden text-left text-xs sm:block sm:pr-2">
|
|
113
|
+
<div class="w-20 truncate">
|
|
114
|
+
<span class="font-semibold text-black">{user?.firstName}</span>
|
|
115
|
+
</div>
|
|
116
|
+
{#if user?.role}
|
|
117
|
+
<div class="w-20 truncate text-gray-500">
|
|
118
|
+
<span>{user.role}</span>
|
|
119
|
+
</div>
|
|
120
|
+
{:else}
|
|
121
|
+
<p class="flex w-20 truncate text-gray-500">{user?.username}</p>
|
|
122
|
+
{/if}
|
|
123
|
+
</div>
|
|
124
|
+
</Button>
|
|
125
|
+
{#if showUser}
|
|
126
|
+
<div class="relative">
|
|
127
|
+
<div
|
|
128
|
+
class="absolute right-0 z-10 mt-2 rounded-md bg-white
|
|
129
|
+
py-2 shadow-md shadow-gray-300
|
|
130
|
+
"
|
|
131
|
+
transition:slide
|
|
132
|
+
use:clickOutsideAction
|
|
133
|
+
>
|
|
134
|
+
<div class="space-y-2 px-4 py-2">
|
|
135
|
+
<span class="block truncate text-sm font-bold">{user?.fullName}</span>
|
|
136
|
+
<div class="block truncate text-sm">
|
|
137
|
+
<span class="font-light text-gray-500">Role:</span>
|
|
138
|
+
<span class="font-bold">{user?.role}</span>
|
|
139
|
+
</div>
|
|
140
|
+
<div class="block truncate text-sm">
|
|
141
|
+
<span class="font-light text-gray-500">Username:</span>
|
|
142
|
+
<span class="font-bold">{user?.username}</span>
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
<DropdownDivider />
|
|
146
|
+
<div class="grid">
|
|
147
|
+
<Button
|
|
148
|
+
ripple={false}
|
|
149
|
+
class="mx-0.5 flex justify-start gap-1 border bg-red-50 text-red-600 hover:bg-red-100"
|
|
150
|
+
onclick={() => {
|
|
151
|
+
showUser = false;
|
|
152
|
+
onsignout?.();
|
|
153
|
+
}}
|
|
154
|
+
>
|
|
155
|
+
{#snippet leadingIcon()}
|
|
156
|
+
<iconify-icon icon="stash:signout" style="font-size: 20px;"></iconify-icon>
|
|
157
|
+
{/snippet}
|
|
158
|
+
Sign Out
|
|
159
|
+
</Button>
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
{/if}
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
</nav>
|