tera-system-ui 0.0.21 → 0.0.22
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/dist/components/avatar/Avatar.d.ts +82 -0
- package/dist/components/avatar/Avatar.js +35 -0
- package/dist/components/avatar/Avatar.svelte +43 -0
- package/dist/components/avatar/Avatar.svelte.d.ts +3 -0
- package/dist/components/avatar/index.d.ts +1 -0
- package/dist/components/avatar/index.js +1 -0
- package/dist/components/dropdown-menu/DropdownMenu.d.ts +22 -0
- package/dist/components/dropdown-menu/DropdownMenu.js +15 -0
- package/dist/components/dropdown-menu/components/DropdownMenu.svelte +34 -0
- package/dist/components/dropdown-menu/components/DropdownMenu.svelte.d.ts +3 -0
- package/dist/components/dropdown-menu/components/DropdownMenuGroup.svelte +12 -0
- package/dist/components/dropdown-menu/components/DropdownMenuGroup.svelte.d.ts +5 -0
- package/dist/components/dropdown-menu/components/DropdownMenuHeader.svelte +12 -0
- package/dist/components/dropdown-menu/components/DropdownMenuHeader.svelte.d.ts +5 -0
- package/dist/components/dropdown-menu/components/DropdownMenuItem.svelte +30 -0
- package/dist/components/dropdown-menu/components/DropdownMenuItem.svelte.d.ts +3 -0
- package/dist/components/dropdown-menu/components/DropdownMenuSeparator.svelte +11 -0
- package/dist/components/dropdown-menu/components/DropdownMenuSeparator.svelte.d.ts +5 -0
- package/dist/components/dropdown-menu/index.d.ts +5 -0
- package/dist/components/dropdown-menu/index.js +5 -0
- package/dist/components/icons/IconLogout.svelte +10 -0
- package/dist/components/icons/IconLogout.svelte.d.ts +4 -0
- package/dist/components/icons/IconSettings.svelte +10 -0
- package/dist/components/icons/IconSettings.svelte.d.ts +4 -0
- package/dist/components/icons/index.d.ts +2 -0
- package/dist/components/icons/index.js +2 -0
- package/dist/components/popover/Popover.svelte +25 -3
- package/dist/components/tera-ui-context/TeraUiContext.d.ts +1 -0
- package/dist/components/user-avatar-with-menu/UserAvatarWithMenu.d.ts +11 -0
- package/dist/components/user-avatar-with-menu/UserAvatarWithMenu.js +7 -0
- package/dist/components/user-avatar-with-menu/UserAvatarWithMenu.svelte +68 -0
- package/dist/components/user-avatar-with-menu/UserAvatarWithMenu.svelte.d.ts +3 -0
- package/dist/components/user-avatar-with-menu/index.d.ts +1 -0
- package/dist/components/user-avatar-with-menu/index.js +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +4 -1
- package/dist/internal/service/user.service.d.ts +2 -0
- package/dist/internal/service/user.service.js +20 -0
- package/dist/types/user-data.d.ts +31 -0
- package/dist/types/user-data.js +1 -0
- package/package.json +4 -3
- package/scripts/add-component-template.js +1 -1
- package/scripts/generate-ts-index.js +8 -6
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { type VariantProps } from "tailwind-variants";
|
|
2
|
+
export declare const styles: import("tailwind-variants").TVReturnType<{
|
|
3
|
+
size: {
|
|
4
|
+
sm: string;
|
|
5
|
+
md: string;
|
|
6
|
+
lg: string;
|
|
7
|
+
xl: string;
|
|
8
|
+
};
|
|
9
|
+
border: {
|
|
10
|
+
true: string;
|
|
11
|
+
};
|
|
12
|
+
}, undefined, "relative rounded-full object-cover bg-primary-token-1 select-none grid place-content-center leading-none font-bold overflow-clip hover:brightness-90", import("tailwind-variants/dist/config").TVConfig<{
|
|
13
|
+
size: {
|
|
14
|
+
sm: string;
|
|
15
|
+
md: string;
|
|
16
|
+
lg: string;
|
|
17
|
+
xl: string;
|
|
18
|
+
};
|
|
19
|
+
border: {
|
|
20
|
+
true: string;
|
|
21
|
+
};
|
|
22
|
+
}, {
|
|
23
|
+
size: {
|
|
24
|
+
sm: string;
|
|
25
|
+
md: string;
|
|
26
|
+
lg: string;
|
|
27
|
+
xl: string;
|
|
28
|
+
};
|
|
29
|
+
border: {
|
|
30
|
+
true: string;
|
|
31
|
+
};
|
|
32
|
+
}>, {
|
|
33
|
+
size: {
|
|
34
|
+
sm: string;
|
|
35
|
+
md: string;
|
|
36
|
+
lg: string;
|
|
37
|
+
xl: string;
|
|
38
|
+
};
|
|
39
|
+
border: {
|
|
40
|
+
true: string;
|
|
41
|
+
};
|
|
42
|
+
}, undefined, import("tailwind-variants").TVReturnType<{
|
|
43
|
+
size: {
|
|
44
|
+
sm: string;
|
|
45
|
+
md: string;
|
|
46
|
+
lg: string;
|
|
47
|
+
xl: string;
|
|
48
|
+
};
|
|
49
|
+
border: {
|
|
50
|
+
true: string;
|
|
51
|
+
};
|
|
52
|
+
}, undefined, "relative rounded-full object-cover bg-primary-token-1 select-none grid place-content-center leading-none font-bold overflow-clip hover:brightness-90", import("tailwind-variants/dist/config").TVConfig<{
|
|
53
|
+
size: {
|
|
54
|
+
sm: string;
|
|
55
|
+
md: string;
|
|
56
|
+
lg: string;
|
|
57
|
+
xl: string;
|
|
58
|
+
};
|
|
59
|
+
border: {
|
|
60
|
+
true: string;
|
|
61
|
+
};
|
|
62
|
+
}, {
|
|
63
|
+
size: {
|
|
64
|
+
sm: string;
|
|
65
|
+
md: string;
|
|
66
|
+
lg: string;
|
|
67
|
+
xl: string;
|
|
68
|
+
};
|
|
69
|
+
border: {
|
|
70
|
+
true: string;
|
|
71
|
+
};
|
|
72
|
+
}>, unknown, unknown, undefined>>;
|
|
73
|
+
type AvatarVariants = VariantProps<typeof styles>;
|
|
74
|
+
export interface AvatarProps extends AvatarVariants {
|
|
75
|
+
children?: any;
|
|
76
|
+
class?: string;
|
|
77
|
+
alt?: string;
|
|
78
|
+
src?: string;
|
|
79
|
+
ref?: any;
|
|
80
|
+
userUid?: string;
|
|
81
|
+
}
|
|
82
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { tv } from "tailwind-variants";
|
|
2
|
+
export const styles = tv({
|
|
3
|
+
base: 'relative rounded-full object-cover bg-primary-token-1 select-none grid place-content-center leading-none font-bold overflow-clip hover:brightness-90',
|
|
4
|
+
variants: {
|
|
5
|
+
size: {
|
|
6
|
+
sm: 'size-8 text-xs',
|
|
7
|
+
md: 'size-10 text-sm',
|
|
8
|
+
lg: 'size-12 font-bold',
|
|
9
|
+
xl: 'size-16 text-xl font-bold',
|
|
10
|
+
},
|
|
11
|
+
border: {
|
|
12
|
+
true: 'border-[4px] border-primary-token-6'
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
compoundVariants: [
|
|
16
|
+
{
|
|
17
|
+
size: 'sm',
|
|
18
|
+
border: true,
|
|
19
|
+
class: 'border-[2px]'
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
size: ['md', 'lg'],
|
|
23
|
+
border: true,
|
|
24
|
+
class: 'border-[3px]'
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
size: ['xl'],
|
|
28
|
+
border: true,
|
|
29
|
+
class: 'border-[4px]'
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
defaultVariants: {
|
|
33
|
+
size: 'md',
|
|
34
|
+
},
|
|
35
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {type AvatarProps, styles} from "./Avatar";
|
|
3
|
+
import {getUserAvatarUrl} from "../../internal/service/user.service";
|
|
4
|
+
import {cn} from "../../utils/utils";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
children,
|
|
8
|
+
alt = 'Avatar',
|
|
9
|
+
size = 'md',
|
|
10
|
+
src,
|
|
11
|
+
class: className,
|
|
12
|
+
border = true,
|
|
13
|
+
ref = $bindable(),
|
|
14
|
+
userUid,
|
|
15
|
+
...props
|
|
16
|
+
}: AvatarProps = $props();
|
|
17
|
+
|
|
18
|
+
let isError = $state()
|
|
19
|
+
|
|
20
|
+
function handleErrorImage() {
|
|
21
|
+
isError = true
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let imgUrl = src ? src : userUid ? getUserAvatarUrl(userUid) : undefined
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<div bind:this={ref}
|
|
28
|
+
class={styles({ size, className, border })} {...props}>
|
|
29
|
+
{#if imgUrl && !isError}
|
|
30
|
+
<img src={imgUrl} alt={alt} onerror={handleErrorImage} class="w-full h-full object-cover"/>
|
|
31
|
+
{:else}
|
|
32
|
+
<span class="leading-none">
|
|
33
|
+
{@render children?.()}
|
|
34
|
+
</span>
|
|
35
|
+
{/if}
|
|
36
|
+
<div class={
|
|
37
|
+
cn("absolute inset-[0px] border-[2px] border-neutral-token-2 rounded-full", {
|
|
38
|
+
'border-[3px]' : size === 'lg' || size === 'xl',
|
|
39
|
+
})
|
|
40
|
+
}>
|
|
41
|
+
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Avatar } from './Avatar.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Avatar } from './Avatar.svelte';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type VariantProps } from "tailwind-variants";
|
|
2
|
+
export declare const styles: import("tailwind-variants").TVReturnType<{}, undefined, "", import("tailwind-variants/dist/config").TVConfig<{}, {}>, {}, undefined, import("tailwind-variants").TVReturnType<{}, undefined, "", import("tailwind-variants/dist/config").TVConfig<{}, {}>, unknown, unknown, undefined>>;
|
|
3
|
+
type DropdownMenuVariants = VariantProps<typeof styles>;
|
|
4
|
+
export interface DropdownMenuProps extends DropdownMenuVariants {
|
|
5
|
+
children?: any;
|
|
6
|
+
class?: string;
|
|
7
|
+
triggerRef: any;
|
|
8
|
+
open?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export type DropdownMenuContext = {
|
|
11
|
+
setOpen: (open: boolean) => void;
|
|
12
|
+
getOpen: () => boolean;
|
|
13
|
+
};
|
|
14
|
+
export declare function getCtx(): DropdownMenuContext;
|
|
15
|
+
export declare function setCtx(context: DropdownMenuContext): void;
|
|
16
|
+
export type DropdownMenuItemProps = {
|
|
17
|
+
children?: any;
|
|
18
|
+
class?: string;
|
|
19
|
+
onclick?: (e: any) => void;
|
|
20
|
+
href?: string;
|
|
21
|
+
};
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { tv } from "tailwind-variants";
|
|
2
|
+
import { getContext, setContext } from "svelte";
|
|
3
|
+
export const styles = tv({
|
|
4
|
+
base: '',
|
|
5
|
+
variants: {},
|
|
6
|
+
compoundVariants: [],
|
|
7
|
+
defaultVariants: {},
|
|
8
|
+
});
|
|
9
|
+
const CONTEXT_NAME = 'DropdownMenu';
|
|
10
|
+
export function getCtx() {
|
|
11
|
+
return getContext(CONTEXT_NAME);
|
|
12
|
+
}
|
|
13
|
+
export function setCtx(context) {
|
|
14
|
+
setContext(CONTEXT_NAME, context);
|
|
15
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {type DropdownMenuProps, setCtx} from "../DropdownMenu";
|
|
3
|
+
import {Popover} from "../../popover";
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
children,
|
|
7
|
+
open = $bindable(),
|
|
8
|
+
triggerRef,
|
|
9
|
+
|
|
10
|
+
...props
|
|
11
|
+
}: DropdownMenuProps = $props();
|
|
12
|
+
|
|
13
|
+
function setOpen(o: boolean) {
|
|
14
|
+
open = o;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
setCtx({
|
|
18
|
+
setOpen,
|
|
19
|
+
getOpen: () => !!open
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<Popover
|
|
25
|
+
triggerRef={triggerRef}
|
|
26
|
+
offset={4}
|
|
27
|
+
bind:open
|
|
28
|
+
class=""
|
|
29
|
+
flip="true"
|
|
30
|
+
role="menu"
|
|
31
|
+
{...props}
|
|
32
|
+
>
|
|
33
|
+
{@render children?.()}
|
|
34
|
+
</Popover>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {cn} from "../../../utils/utils";
|
|
3
|
+
|
|
4
|
+
let {children, class: className, ...props} = $props()
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<div class={cn('p-1', className)}
|
|
8
|
+
data-dropdown-menu-group
|
|
9
|
+
role="group"
|
|
10
|
+
{...props}>
|
|
11
|
+
{@render children?.()}
|
|
12
|
+
</div>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {cn} from "../../../utils/utils";
|
|
3
|
+
|
|
4
|
+
let {children, class: className, ...props} = $props()
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<div class={cn('px-3 py-1.5 font-semibold', className)}
|
|
8
|
+
data-dropdown-menu-header
|
|
9
|
+
role="group"
|
|
10
|
+
{...props}>
|
|
11
|
+
{@render children?.()}
|
|
12
|
+
</div>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {type DropdownMenuItemProps, getCtx} from "../DropdownMenu";
|
|
3
|
+
import {cn} from "../../../utils/utils";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
let {children, class: className, onclick, href, ...props}: DropdownMenuItemProps = $props()
|
|
7
|
+
let context = getCtx()
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
{#snippet button()}
|
|
11
|
+
<button
|
|
12
|
+
onclick={(e) => {
|
|
13
|
+
onclick?.(e)
|
|
14
|
+
context?.setOpen(false)
|
|
15
|
+
}}
|
|
16
|
+
role="menuitem"
|
|
17
|
+
data-dropdown-menu-item
|
|
18
|
+
class={cn('flex w-full items-center gap-2 px-2 py-2 rounded hover:bg-neutral-token-4 transition-all', className)}
|
|
19
|
+
{...props}>
|
|
20
|
+
{@render children?.()}
|
|
21
|
+
</button>
|
|
22
|
+
{/snippet}
|
|
23
|
+
|
|
24
|
+
{#if href}
|
|
25
|
+
<a href={href}>
|
|
26
|
+
{@render button()}
|
|
27
|
+
</a>
|
|
28
|
+
{:else }
|
|
29
|
+
{@render button()}
|
|
30
|
+
{/if}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as DropdownMenu } from './components/DropdownMenu.svelte';
|
|
2
|
+
export { default as DropdownMenuItem } from './components/DropdownMenuItem.svelte';
|
|
3
|
+
export { default as DropdownMenuGroup } from './components/DropdownMenuGroup.svelte';
|
|
4
|
+
export { default as DropdownMenuHeader } from './components/DropdownMenuHeader.svelte';
|
|
5
|
+
export { default as DropdownMenuSeparator } from './components/DropdownMenuSeparator.svelte';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as DropdownMenu } from './components/DropdownMenu.svelte';
|
|
2
|
+
export { default as DropdownMenuItem } from './components/DropdownMenuItem.svelte';
|
|
3
|
+
export { default as DropdownMenuGroup } from './components/DropdownMenuGroup.svelte';
|
|
4
|
+
export { default as DropdownMenuHeader } from './components/DropdownMenuHeader.svelte';
|
|
5
|
+
export { default as DropdownMenuSeparator } from './components/DropdownMenuSeparator.svelte';
|
|
@@ -9,9 +9,11 @@ export { default as IconCopyCheckFilled } from './IconCopyCheckFilled.svelte';
|
|
|
9
9
|
export { default as IconHamburger } from './IconHamburger.svelte';
|
|
10
10
|
export { default as IconLanguage } from './IconLanguage.svelte';
|
|
11
11
|
export { default as IconLoader2 } from './IconLoader2.svelte';
|
|
12
|
+
export { default as IconLogout } from './IconLogout.svelte';
|
|
12
13
|
export { default as IconMoon } from './IconMoon.svelte';
|
|
13
14
|
export { default as IconPointFilled } from './IconPointFilled.svelte';
|
|
14
15
|
export { default as IconSearch } from './IconSearch.svelte';
|
|
16
|
+
export { default as IconSettings } from './IconSettings.svelte';
|
|
15
17
|
export { default as IconSun } from './IconSun.svelte';
|
|
16
18
|
export { default as IconSwitchHorizontal } from './IconSwitchHorizontal.svelte';
|
|
17
19
|
export { default as IconSwitchVertical } from './IconSwitchVertical.svelte';
|
|
@@ -9,9 +9,11 @@ export { default as IconCopyCheckFilled } from './IconCopyCheckFilled.svelte';
|
|
|
9
9
|
export { default as IconHamburger } from './IconHamburger.svelte';
|
|
10
10
|
export { default as IconLanguage } from './IconLanguage.svelte';
|
|
11
11
|
export { default as IconLoader2 } from './IconLoader2.svelte';
|
|
12
|
+
export { default as IconLogout } from './IconLogout.svelte';
|
|
12
13
|
export { default as IconMoon } from './IconMoon.svelte';
|
|
13
14
|
export { default as IconPointFilled } from './IconPointFilled.svelte';
|
|
14
15
|
export { default as IconSearch } from './IconSearch.svelte';
|
|
16
|
+
export { default as IconSettings } from './IconSettings.svelte';
|
|
15
17
|
export { default as IconSun } from './IconSun.svelte';
|
|
16
18
|
export { default as IconSwitchHorizontal } from './IconSwitchHorizontal.svelte';
|
|
17
19
|
export { default as IconSwitchVertical } from './IconSwitchVertical.svelte';
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import {clickOutside} from "../../actions/clickOutside"
|
|
7
7
|
import {onDestroy, onMount} from "svelte";
|
|
8
|
+
import {circInOut} from "svelte/easing";
|
|
8
9
|
|
|
9
10
|
let {
|
|
10
11
|
children,
|
|
@@ -41,8 +42,10 @@
|
|
|
41
42
|
offset(offsetAmount),
|
|
42
43
|
size({
|
|
43
44
|
apply({rects, elements}) {
|
|
45
|
+
console.log(elements.reference)
|
|
44
46
|
Object.assign(elements.floating.style, {
|
|
45
47
|
minWidth: `${rects.reference.width}px`,
|
|
48
|
+
maxWidth: `${window.innerWidth - 16}px`,
|
|
46
49
|
});
|
|
47
50
|
},
|
|
48
51
|
}),
|
|
@@ -116,14 +119,36 @@
|
|
|
116
119
|
cleanup?.()
|
|
117
120
|
}
|
|
118
121
|
})
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
function spin(node, {duration}) {
|
|
125
|
+
return {
|
|
126
|
+
duration,
|
|
127
|
+
css: (t) => {
|
|
128
|
+
const eased = circInOut(t);
|
|
129
|
+
return `
|
|
130
|
+
transform-origin: 0% 0%;
|
|
131
|
+
transform: translateY(${eased * 10 - 10}px) scaleY(${eased * 0.05 + 0.95});
|
|
132
|
+
opacity: ${eased};
|
|
133
|
+
`
|
|
134
|
+
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
|
|
119
140
|
</script>
|
|
120
141
|
|
|
121
142
|
<!-- Popover Content -->
|
|
122
143
|
{#if open}
|
|
123
144
|
<div bind:this={popover}
|
|
145
|
+
data-open={open}
|
|
124
146
|
class={cn("overflow-hidden absolute z-10 bg-neutral-token-1 shadow-2xl rounded-container border border-neutral-token-5", className)}
|
|
125
147
|
use:clickOutside={{exceptElement: triggerRef}}
|
|
126
148
|
onclick_outside={handleClickOutside}
|
|
149
|
+
|
|
150
|
+
in:spin={{ duration: 200 }}
|
|
151
|
+
out:spin={{ duration: 200 }}
|
|
127
152
|
{...props}
|
|
128
153
|
>
|
|
129
154
|
<!-- <div bind:this={arrowElement} class="size-2 absolute rotate-45 bg-inherit"></div>-->
|
|
@@ -132,6 +157,3 @@
|
|
|
132
157
|
{/if}
|
|
133
158
|
|
|
134
159
|
|
|
135
|
-
<style>
|
|
136
|
-
|
|
137
|
-
</style>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type VariantProps } from "tailwind-variants";
|
|
2
|
+
import type { UserData } from "../../types/user-data";
|
|
3
|
+
export declare const styles: import("tailwind-variants").TVReturnType<{}, undefined, "", import("tailwind-variants/dist/config").TVConfig<{}, {}>, {}, undefined, import("tailwind-variants").TVReturnType<{}, undefined, "", import("tailwind-variants/dist/config").TVConfig<{}, {}>, unknown, unknown, undefined>>;
|
|
4
|
+
type UserAvatarWithMenuVariants = VariantProps<typeof styles>;
|
|
5
|
+
export interface UserAvatarWithMenuProps extends UserAvatarWithMenuVariants {
|
|
6
|
+
children?: any;
|
|
7
|
+
class?: string;
|
|
8
|
+
user?: UserData;
|
|
9
|
+
onLogout?: () => void;
|
|
10
|
+
}
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {type UserAvatarWithMenuProps} from "./UserAvatarWithMenu";
|
|
3
|
+
import {Avatar} from "../avatar";
|
|
4
|
+
import {
|
|
5
|
+
DropdownMenu,
|
|
6
|
+
DropdownMenuGroup,
|
|
7
|
+
DropdownMenuHeader,
|
|
8
|
+
DropdownMenuItem,
|
|
9
|
+
DropdownMenuSeparator
|
|
10
|
+
} from "../dropdown-menu";
|
|
11
|
+
import {IconLogout, IconSettings} from "../icons";
|
|
12
|
+
import {extractShortUsernameFromEmail} from "../../internal/service/user.service";
|
|
13
|
+
|
|
14
|
+
let {children, user, onLogout,...props}: UserAvatarWithMenuProps = $props();
|
|
15
|
+
|
|
16
|
+
let shortUserName = extractShortUsernameFromEmail(user.email)
|
|
17
|
+
let triggerRef = $state()
|
|
18
|
+
let open = $state(true)
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
{#if user}
|
|
23
|
+
<button bind:this={triggerRef}>
|
|
24
|
+
<Avatar
|
|
25
|
+
userUid={user.userUid}
|
|
26
|
+
>
|
|
27
|
+
{shortUserName}
|
|
28
|
+
</Avatar>
|
|
29
|
+
</button>
|
|
30
|
+
|
|
31
|
+
<DropdownMenu
|
|
32
|
+
bind:open
|
|
33
|
+
triggerRef={triggerRef}
|
|
34
|
+
class="!min-w-[14rem]"
|
|
35
|
+
>
|
|
36
|
+
<DropdownMenuHeader>
|
|
37
|
+
<div class="grid grid-cols-[auto,1fr] gap-2 overflow-hidden break-all items-center">
|
|
38
|
+
<Avatar border={false}
|
|
39
|
+
size="lg"
|
|
40
|
+
userUid={user.userUid}
|
|
41
|
+
>
|
|
42
|
+
{shortUserName}
|
|
43
|
+
</Avatar>
|
|
44
|
+
{#if user.email}
|
|
45
|
+
{user.email}
|
|
46
|
+
{/if}
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
</DropdownMenuHeader>
|
|
50
|
+
<DropdownMenuSeparator/>
|
|
51
|
+
|
|
52
|
+
<DropdownMenuGroup>
|
|
53
|
+
<DropdownMenuItem
|
|
54
|
+
href="/account-settings"
|
|
55
|
+
>
|
|
56
|
+
<IconSettings/>
|
|
57
|
+
Account Settings
|
|
58
|
+
</DropdownMenuItem>
|
|
59
|
+
</DropdownMenuGroup>
|
|
60
|
+
<DropdownMenuSeparator/>
|
|
61
|
+
<DropdownMenuGroup>
|
|
62
|
+
<DropdownMenuItem onclick={onLogout}>
|
|
63
|
+
<IconLogout/>
|
|
64
|
+
Logout
|
|
65
|
+
</DropdownMenuItem>
|
|
66
|
+
</DropdownMenuGroup>
|
|
67
|
+
</DropdownMenu>
|
|
68
|
+
{/if}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as UserAvatarWithMenu } from './UserAvatarWithMenu.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as UserAvatarWithMenu } from './UserAvatarWithMenu.svelte';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
export { Avatar } from './components/avatar';
|
|
1
2
|
export { BrandLogo } from './components/brand-logo';
|
|
2
3
|
export { Button } from './components/button';
|
|
3
4
|
export { Combobox } from './components/combobox';
|
|
4
5
|
export { Command } from './components/command';
|
|
5
6
|
export { Dialog, DialogAstro } from './components/dialog';
|
|
7
|
+
export { DropdownMenu, DropdownMenuItem, DropdownMenuGroup, DropdownMenuHeader, DropdownMenuSeparator } from './components/dropdown-menu';
|
|
6
8
|
export { Header } from './components/header';
|
|
7
|
-
export { IconArrowBigRightFilled, IconBook, IconBookmarkPlus, IconCalculator, IconCheck, IconChevronDown, IconCopy, IconCopyCheckFilled, IconHamburger, IconLanguage, IconLoader2, IconMoon, IconPointFilled, IconSearch, IconSun, IconSwitchHorizontal, IconSwitchVertical, IconTransform, IconX } from './components/icons';
|
|
9
|
+
export { IconArrowBigRightFilled, IconBook, IconBookmarkPlus, IconCalculator, IconCheck, IconChevronDown, IconCopy, IconCopyCheckFilled, IconHamburger, IconLanguage, IconLoader2, IconLogout, IconMoon, IconPointFilled, IconSearch, IconSettings, IconSun, IconSwitchHorizontal, IconSwitchVertical, IconTransform, IconX } from './components/icons';
|
|
8
10
|
export { Input } from './components/input';
|
|
9
11
|
export { LanguagePickerButton } from './components/language-picker-button';
|
|
10
12
|
export { LightDarkToggle } from './components/light-dark-toggle';
|
|
@@ -12,3 +14,4 @@ export { Popover } from './components/popover';
|
|
|
12
14
|
export { PopoverResponsive } from './components/popover-responsive';
|
|
13
15
|
export { SideNavigation, SideNavigationLayout, toggleSideNavigation } from './components/side-navigation';
|
|
14
16
|
export { TeraUiContext } from './components/tera-ui-context';
|
|
17
|
+
export { UserAvatarWithMenu } from './components/user-avatar-with-menu';
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
export { Avatar } from './components/avatar';
|
|
1
2
|
export { BrandLogo } from './components/brand-logo';
|
|
2
3
|
export { Button } from './components/button';
|
|
3
4
|
export { Combobox } from './components/combobox';
|
|
4
5
|
export { Command } from './components/command';
|
|
5
6
|
export { Dialog, DialogAstro } from './components/dialog';
|
|
7
|
+
export { DropdownMenu, DropdownMenuItem, DropdownMenuGroup, DropdownMenuHeader, DropdownMenuSeparator } from './components/dropdown-menu';
|
|
6
8
|
export { Header } from './components/header';
|
|
7
|
-
export { IconArrowBigRightFilled, IconBook, IconBookmarkPlus, IconCalculator, IconCheck, IconChevronDown, IconCopy, IconCopyCheckFilled, IconHamburger, IconLanguage, IconLoader2, IconMoon, IconPointFilled, IconSearch, IconSun, IconSwitchHorizontal, IconSwitchVertical, IconTransform, IconX } from './components/icons';
|
|
9
|
+
export { IconArrowBigRightFilled, IconBook, IconBookmarkPlus, IconCalculator, IconCheck, IconChevronDown, IconCopy, IconCopyCheckFilled, IconHamburger, IconLanguage, IconLoader2, IconLogout, IconMoon, IconPointFilled, IconSearch, IconSettings, IconSun, IconSwitchHorizontal, IconSwitchVertical, IconTransform, IconX } from './components/icons';
|
|
8
10
|
export { Input } from './components/input';
|
|
9
11
|
export { LanguagePickerButton } from './components/language-picker-button';
|
|
10
12
|
export { LightDarkToggle } from './components/light-dark-toggle';
|
|
@@ -12,3 +14,4 @@ export { Popover } from './components/popover';
|
|
|
12
14
|
export { PopoverResponsive } from './components/popover-responsive';
|
|
13
15
|
export { SideNavigation, SideNavigationLayout, toggleSideNavigation } from './components/side-navigation';
|
|
14
16
|
export { TeraUiContext } from './components/tera-ui-context';
|
|
17
|
+
export { UserAvatarWithMenu } from './components/user-avatar-with-menu';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { getGlobalContext } from "../../components/tera-ui-context/global-context";
|
|
2
|
+
export function extractShortUsernameFromEmail(email) {
|
|
3
|
+
if (!email || typeof email !== 'string') {
|
|
4
|
+
return '?';
|
|
5
|
+
}
|
|
6
|
+
// Extract the part before the '@' symbol
|
|
7
|
+
const usernamePart = email.split('@')[0];
|
|
8
|
+
// Replace any non-alphanumeric characters with a space and trim extra spaces
|
|
9
|
+
const cleanUsername = usernamePart.replace(/[^a-zA-Z0-9]/g, ' ').trim();
|
|
10
|
+
// Split the username into words and create an initialism
|
|
11
|
+
const words = cleanUsername.split(' ');
|
|
12
|
+
let shortForm = words.map(word => word[0]).join('');
|
|
13
|
+
// Ensure the result is between 1 to 4 characters
|
|
14
|
+
shortForm = shortForm.slice(0, 4).toUpperCase();
|
|
15
|
+
return shortForm || '?';
|
|
16
|
+
}
|
|
17
|
+
export function getUserAvatarUrl(userUid) {
|
|
18
|
+
let baseUrl = `${getGlobalContext().apiUrl || 'https://hoidap.xyz/api/v1'}/users`;
|
|
19
|
+
return `${baseUrl}/avatar/${encodeURI(userUid)}`;
|
|
20
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface UserData {
|
|
2
|
+
displayName?: string;
|
|
3
|
+
profileImage?: any;
|
|
4
|
+
registerAt?: Date;
|
|
5
|
+
totalAnswer?: number;
|
|
6
|
+
totalQuestion?: number;
|
|
7
|
+
totalThanks?: number;
|
|
8
|
+
username?: string;
|
|
9
|
+
userUid?: string;
|
|
10
|
+
roleId?: string;
|
|
11
|
+
reputation?: string;
|
|
12
|
+
lastAccessDate?: string;
|
|
13
|
+
websiteUrl?: string;
|
|
14
|
+
location?: string;
|
|
15
|
+
aboutMe?: string;
|
|
16
|
+
views?: number;
|
|
17
|
+
upVotes?: number;
|
|
18
|
+
downVotes?: number;
|
|
19
|
+
passwordHash?: string;
|
|
20
|
+
mobile?: string;
|
|
21
|
+
email?: string;
|
|
22
|
+
data?: Map<any, any>;
|
|
23
|
+
jwtToken?: JwtToken;
|
|
24
|
+
userData?: string;
|
|
25
|
+
emailVerified?: boolean;
|
|
26
|
+
didResetPassword?: boolean;
|
|
27
|
+
language?: string;
|
|
28
|
+
suspended?: boolean;
|
|
29
|
+
registeredAtLocation?: string;
|
|
30
|
+
registeredFromSource?: string;
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tera-system-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.22",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "vite dev",
|
|
6
6
|
"build": "vite build && npm run package",
|
|
@@ -8,12 +8,13 @@
|
|
|
8
8
|
"package": "svelte-kit sync && svelte-package && publint",
|
|
9
9
|
"customPrepublish": "node ./scripts/prepublish.js",
|
|
10
10
|
"postpublish": "node ./scripts/postpublish.js",
|
|
11
|
-
"prepublishOnly": "npm run lang-compile && npm run customPrepublish && npm run package",
|
|
11
|
+
"prepublishOnly": "npm run lang-compile && npm run customPrepublish && npm run generate-index && npm run package",
|
|
12
12
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
13
13
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
14
14
|
"storybook": "storybook dev -p 6006",
|
|
15
15
|
"build-storybook": "storybook build",
|
|
16
|
-
"lang-compile": "paraglide-js compile --project ./project.inlang --outdir ./src/lib/paraglide"
|
|
16
|
+
"lang-compile": "paraglide-js compile --project ./project.inlang --outdir ./src/lib/paraglide",
|
|
17
|
+
"generate-index": "node ./scripts/generate-ts-index.js"
|
|
17
18
|
},
|
|
18
19
|
"bin": {
|
|
19
20
|
"ui": "./scripts/add-component-template.js",
|
|
@@ -44,8 +44,8 @@ function extractExportNames(filePath) {
|
|
|
44
44
|
const exportNames = [];
|
|
45
45
|
|
|
46
46
|
// Regular expressions to match the export names
|
|
47
|
-
const defaultExportRegex =
|
|
48
|
-
const namedExportRegex =
|
|
47
|
+
const defaultExportRegex = /^(?!\s*\/\/)\s*export\s*{\s*default\s+as\s+(\w+)/gm;
|
|
48
|
+
const namedExportRegex = /^(?!\s*\/\/)\s*export\s*{(\w+)\s*}/gm;
|
|
49
49
|
|
|
50
50
|
let match;
|
|
51
51
|
|
|
@@ -72,8 +72,9 @@ function extractExportNames(filePath) {
|
|
|
72
72
|
function findFilesByPattern(folderPath, namePattern) {
|
|
73
73
|
const result = [];
|
|
74
74
|
|
|
75
|
+
console.log(folderPath)
|
|
75
76
|
function searchFolder(currentPath) {
|
|
76
|
-
const filesAndDirs = fs.
|
|
77
|
+
const filesAndDirs = fs.readdirSync(currentPath);
|
|
77
78
|
|
|
78
79
|
for (const item of filesAndDirs) {
|
|
79
80
|
const itemPath = path.join(currentPath, item);
|
|
@@ -93,9 +94,10 @@ function findFilesByPattern(folderPath, namePattern) {
|
|
|
93
94
|
return result;
|
|
94
95
|
}
|
|
95
96
|
|
|
96
|
-
const
|
|
97
|
-
const
|
|
98
|
-
const
|
|
97
|
+
const baseLib = './src/lib'
|
|
98
|
+
const GLOBAL_INDEX_PATH = baseLib + "/index.ts"
|
|
99
|
+
const COMPONENTS_PATH = baseLib + "/components"
|
|
100
|
+
const ICON_COMPONENTS_PATH = baseLib + "/components/icons"
|
|
99
101
|
|
|
100
102
|
const iconComponentsFileList = findFilesByPattern(ICON_COMPONENTS_PATH, /^Icon\w*\.svelte$/);
|
|
101
103
|
|