@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.
Files changed (103) hide show
  1. package/README.md +8 -8
  2. package/dist/baseEditor/index.svelte +32 -32
  3. package/dist/builders/filters/FilterBuilder.svelte +641 -641
  4. package/dist/forms/FormCheckbox/FormCheckbox.svelte +53 -53
  5. package/dist/forms/FormClEditor/ClEdito.svelte +68 -68
  6. package/dist/forms/FormDatepicker/FormDatepicker.svelte +159 -159
  7. package/dist/forms/FormFileUpload/FormFileUplad.svelte +134 -134
  8. package/dist/forms/FormInput/FormInput.svelte +87 -87
  9. package/dist/forms/FormRadio/FormRadio.svelte +53 -53
  10. package/dist/forms/FormSelect/FormSelect.svelte +88 -88
  11. package/dist/forms/FormTextarea/FormTextarea.svelte +78 -78
  12. package/dist/forms/button-toggle/ButtonToggle.svelte +119 -119
  13. package/dist/forms/button-toggle/CheckIcon.svelte +28 -28
  14. package/dist/forms/checkbox/Checkbox.svelte +82 -82
  15. package/dist/forms/checkbox/CheckboxButton.svelte +92 -92
  16. package/dist/forms/datepicker/Datepicker.svelte +707 -707
  17. package/dist/forms/form/Form.svelte +69 -69
  18. package/dist/forms/input/Input.svelte +363 -363
  19. package/dist/forms/label/Label.svelte +38 -38
  20. package/dist/forms/radio/Radio.svelte +48 -48
  21. package/dist/forms/radio/RadioButton.svelte +22 -22
  22. package/dist/forms/select/Select.svelte +56 -56
  23. package/dist/forms/textarea/Textarea.svelte +165 -165
  24. package/dist/forms/toggle/Toggle.svelte +70 -70
  25. package/dist/layout/Chat/CategorySelector.svelte +52 -52
  26. package/dist/layout/Chat/ChatEntry.svelte +246 -246
  27. package/dist/layout/Chat/ChatEntrySkeleton.svelte +81 -81
  28. package/dist/layout/Chat/ChatHeader.svelte +172 -172
  29. package/dist/layout/Chat/ChatInput.svelte +207 -207
  30. package/dist/layout/Chat/DraggableWindow.svelte +230 -230
  31. package/dist/layout/Chat/PreviewPage.svelte +182 -182
  32. package/dist/layout/Chat/RichText.svelte +216 -216
  33. package/dist/layout/ComponentCanvas/Canvas.svelte +40 -40
  34. package/dist/layout/ComponentCanvas/ComponentRenderer.svelte +85 -85
  35. package/dist/layout/TF/Content/Content.svelte +21 -21
  36. package/dist/layout/TF/Header/Header.svelte +166 -166
  37. package/dist/layout/TF/Sidebar/Sidebar.svelte +148 -148
  38. package/dist/layout/TF/Wrapper/Wrapper.svelte +17 -17
  39. package/dist/layout/mailing/MailPaginator.svelte +36 -36
  40. package/dist/layout/mailing/MailSidebar.svelte +39 -39
  41. package/dist/layout/mailing/MailToolBar.svelte +174 -174
  42. package/dist/layout/mailing/MailingContent.svelte +10 -10
  43. package/dist/layout/mailing/MailingHeader.svelte +55 -55
  44. package/dist/layout/mailing/MailingMessageCard.svelte +112 -112
  45. package/dist/layout/mailing/MailingMessageViewer.svelte +87 -87
  46. package/dist/layout/mailing/MailingModule.svelte +448 -448
  47. package/dist/styles/docs.css +615 -615
  48. package/dist/styles/tf-layout.css +185 -185
  49. package/dist/themes/ThemeProvider.svelte +20 -20
  50. package/dist/types/index.d.ts +2 -0
  51. package/dist/typography/heading/Heading.svelte +35 -35
  52. package/dist/ui/accordion/Accordion.svelte +49 -49
  53. package/dist/ui/accordion/AccordionItem.svelte +173 -173
  54. package/dist/ui/alert/Alert.svelte +83 -83
  55. package/dist/ui/alertDialog/AlertDialog.svelte +40 -40
  56. package/dist/ui/avatar/Avatar.svelte +77 -77
  57. package/dist/ui/box/Box.svelte +28 -28
  58. package/dist/ui/breadcrumb/Breadcrumb.svelte +39 -39
  59. package/dist/ui/buttons/ActionButton.svelte +234 -234
  60. package/dist/ui/buttons/Button.svelte +102 -102
  61. package/dist/ui/buttons/GradientButton.svelte +59 -59
  62. package/dist/ui/datatable/Datatable.svelte +525 -525
  63. package/dist/ui/drawer/Drawer.svelte +300 -300
  64. package/dist/ui/dropdown/Dropdown.svelte +36 -36
  65. package/dist/ui/dropdown/DropdownDivider.svelte +11 -11
  66. package/dist/ui/dropdown/DropdownGroup.svelte +14 -14
  67. package/dist/ui/dropdown/DropdownHeader.svelte +14 -14
  68. package/dist/ui/dropdown/DropdownItem.svelte +52 -52
  69. package/dist/ui/footer/Footer.svelte +15 -15
  70. package/dist/ui/footer/FooterBrand.svelte +37 -37
  71. package/dist/ui/footer/FooterCopyright.svelte +45 -45
  72. package/dist/ui/footer/FooterIcon.svelte +22 -22
  73. package/dist/ui/footer/FooterLink.svelte +33 -33
  74. package/dist/ui/footer/FooterLinkGroup.svelte +13 -13
  75. package/dist/ui/icons/IconifyIcon.svelte +7 -7
  76. package/dist/ui/indicator/Indicator.svelte +42 -42
  77. package/dist/ui/modal/Modal.svelte +265 -265
  78. package/dist/ui/notificationList/NotificationList.svelte +123 -123
  79. package/dist/ui/pageLoader/PageLoader.svelte +14 -14
  80. package/dist/ui/pageLoader/PageLoader2.svelte +99 -0
  81. package/dist/ui/pageLoader/PageLoader2.svelte.d.ts +24 -0
  82. package/dist/ui/pageLoader/index.d.ts +2 -1
  83. package/dist/ui/pageLoader/index.js +2 -1
  84. package/dist/ui/paginate/Paginate.svelte +96 -96
  85. package/dist/ui/speedDial/SpeedDial.svelte +77 -77
  86. package/dist/ui/speedDial/SpeedDialButton.svelte +75 -75
  87. package/dist/ui/speedDial/SpeedDialTrigger.svelte +79 -79
  88. package/dist/ui/tab/Tab.svelte +93 -67
  89. package/dist/ui/table/Table.svelte +396 -396
  90. package/dist/ui/tableLoader/TableLoader.svelte +24 -24
  91. package/dist/ui/toast/Toast.svelte +337 -337
  92. package/dist/ui/toast/Toast.svelte.d.ts +10 -10
  93. package/dist/ui/toolbar/Toolbar.svelte +59 -59
  94. package/dist/ui/toolbar/ToolbarButton.svelte +56 -56
  95. package/dist/ui/toolbar/ToolbarGroup.svelte +43 -43
  96. package/dist/ui/tooltip/Tooltip.svelte +51 -51
  97. package/dist/utils/Popper.svelte +257 -257
  98. package/dist/utils/closeButton/CloseButton.svelte +88 -88
  99. package/dist/utils/index.d.ts +2 -2
  100. package/dist/utils/index.js +3 -3
  101. package/dist/utils/singleSelection.svelte.js +48 -48
  102. package/dist/youtube/index.svelte +12 -12
  103. 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>