tera-system-ui 0.0.24 → 0.0.25
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.svelte +43 -43
- package/dist/components/brand-logo/BrandLogo.svelte +31 -31
- package/dist/components/button/Button.svelte +49 -49
- package/dist/components/combobox/Combobox.svelte +8 -8
- package/dist/components/command/command.scss +72 -72
- package/dist/components/command/components/Command.svelte +120 -120
- package/dist/components/command/components/Command.svelte.d.ts +1 -1
- package/dist/components/command/components/CommandEmpty.svelte +30 -30
- package/dist/components/command/components/CommandEmpty.svelte.d.ts +1 -1
- package/dist/components/command/components/CommandGroup.svelte +110 -110
- package/dist/components/command/components/CommandGroup.svelte.d.ts +1 -1
- package/dist/components/command/components/CommandInput.svelte +92 -92
- package/dist/components/command/components/CommandInput.svelte.d.ts +1 -1
- package/dist/components/command/components/CommandItem.svelte +110 -110
- package/dist/components/command/components/CommandItem.svelte.d.ts +1 -1
- package/dist/components/command/components/CommandList.svelte +56 -56
- package/dist/components/command/components/CommandLoading.svelte +28 -28
- package/dist/components/command/components/CommandLoading.svelte.d.ts +1 -1
- package/dist/components/command/components/CommandSeparator.svelte +21 -21
- package/dist/components/command/components/CommandSeparator.svelte.d.ts +1 -1
- package/dist/components/dialog/Dialog.astro +64 -64
- package/dist/components/dialog/Dialog.svelte +109 -109
- package/dist/components/dialog/dialog.scss +115 -115
- package/dist/components/dropdown-menu/components/DropdownMenu.svelte +33 -33
- package/dist/components/dropdown-menu/components/DropdownMenuGroup.svelte +11 -11
- package/dist/components/dropdown-menu/components/DropdownMenuHeader.svelte +11 -11
- package/dist/components/dropdown-menu/components/DropdownMenuItem.svelte +30 -30
- package/dist/components/dropdown-menu/components/DropdownMenuSeparator.svelte +10 -10
- package/dist/components/header/Header.svelte +36 -36
- package/dist/components/header/header.scss +19 -19
- package/dist/components/icons/IconArrowBigRightFilled.svelte +10 -10
- package/dist/components/icons/IconBook.svelte +10 -10
- package/dist/components/icons/IconBookmarkPlus.svelte +10 -10
- package/dist/components/icons/IconCalculator.svelte +10 -10
- package/dist/components/icons/IconCheck.svelte +10 -10
- package/dist/components/icons/IconChevronDown.svelte +10 -10
- package/dist/components/icons/IconCopy.svelte +10 -10
- package/dist/components/icons/IconCopyCheckFilled.svelte +10 -10
- package/dist/components/icons/IconHamburger.svelte +10 -10
- package/dist/components/icons/IconLanguage.svelte +10 -10
- package/dist/components/icons/IconLoader2.svelte +10 -10
- package/dist/components/icons/IconLogout.svelte +10 -10
- package/dist/components/icons/IconMoon.svelte +10 -10
- package/dist/components/icons/IconPointFilled.svelte +10 -10
- package/dist/components/icons/IconSearch.svelte +10 -10
- package/dist/components/icons/IconSettings.svelte +10 -10
- package/dist/components/icons/IconSun.svelte +10 -10
- package/dist/components/icons/IconSwitchHorizontal.svelte +10 -10
- package/dist/components/icons/IconSwitchVertical.svelte +10 -10
- package/dist/components/icons/IconTransform.svelte +10 -10
- package/dist/components/icons/IconX.svelte +10 -10
- package/dist/components/input/Input.svelte +24 -24
- package/dist/components/language-picker-button/LanguagePickerButton.svelte +109 -109
- package/dist/components/light-dark-toggle/LightDarkToggle.svelte +36 -36
- package/dist/components/popover/Popover.svelte +159 -159
- package/dist/components/popover-responsive/PopoverResponsive.svelte +87 -87
- package/dist/components/side-navigation/SideNavigation.svelte +114 -114
- package/dist/components/side-navigation/SideNavigationItem.svelte +17 -17
- package/dist/components/side-navigation/SideNavigationLayout.svelte +19 -19
- package/dist/components/side-navigation/sidenav.scss +149 -149
- package/dist/components/slider/Slider.svelte +181 -181
- package/dist/components/star-rating/StarRating.d.ts +10 -0
- package/dist/components/star-rating/StarRating.js +7 -0
- package/dist/components/star-rating/StarRating.svelte +88 -0
- package/dist/components/star-rating/StarRating.svelte.d.ts +3 -0
- package/dist/components/star-rating/index.d.ts +1 -0
- package/dist/components/star-rating/index.js +1 -0
- package/dist/components/tabs/components/Tabs.svelte +47 -47
- package/dist/components/tabs/components/TabsContent.svelte +34 -34
- package/dist/components/tabs/components/TabsItem.svelte +29 -29
- package/dist/components/tabs/components/TabsList.svelte +41 -41
- package/dist/components/tera-ui-context/TeraUiContext.svelte +28 -28
- package/dist/components/text-area/TextArea.svelte +88 -88
- package/dist/components/user-avatar-with-menu/UserAvatarWithMenu.svelte +67 -67
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/themes/scrollbar.scss +37 -37
- package/dist/themes/tera-ui-base.css +208 -208
- package/dist/themes/tw-preset.cjs +153 -153
- package/package.json +98 -98
- package/scripts/add-component-template.js +120 -120
- package/scripts/generate-ts-index.js +138 -138
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import {cn} from "../../../utils/utils";
|
|
3
|
-
import {getCtx} from "../Tabs";
|
|
4
|
-
|
|
5
|
-
let {
|
|
6
|
-
children,
|
|
7
|
-
class: className,
|
|
8
|
-
value,
|
|
9
|
-
...props
|
|
10
|
-
} = $props();
|
|
11
|
-
|
|
12
|
-
let context = getCtx()
|
|
13
|
-
|
|
14
|
-
</script>
|
|
15
|
-
|
|
16
|
-
<div>
|
|
17
|
-
<button class={cn("tab-button font-semibold px-2.5 py-1.5 text-neutral-token-8 hover:text-primary-token-4")}
|
|
18
|
-
data-value={value}
|
|
19
|
-
data-state={value === context.state.currentTab ? 'active' : 'inactive'}
|
|
20
|
-
onclick={() => {
|
|
21
|
-
context.state.currentTab = value
|
|
22
|
-
}}
|
|
23
|
-
>
|
|
24
|
-
{@render children?.()}
|
|
25
|
-
</button>
|
|
26
|
-
</div>
|
|
27
|
-
|
|
28
|
-
<style>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {cn} from "../../../utils/utils";
|
|
3
|
+
import {getCtx} from "../Tabs";
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
children,
|
|
7
|
+
class: className,
|
|
8
|
+
value,
|
|
9
|
+
...props
|
|
10
|
+
} = $props();
|
|
11
|
+
|
|
12
|
+
let context = getCtx()
|
|
13
|
+
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<div>
|
|
17
|
+
<button class={cn("tab-button font-semibold px-2.5 py-1.5 text-neutral-token-8 hover:text-primary-token-4")}
|
|
18
|
+
data-value={value}
|
|
19
|
+
data-state={value === context.state.currentTab ? 'active' : 'inactive'}
|
|
20
|
+
onclick={() => {
|
|
21
|
+
context.state.currentTab = value
|
|
22
|
+
}}
|
|
23
|
+
>
|
|
24
|
+
{@render children?.()}
|
|
25
|
+
</button>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<style>
|
|
29
29
|
button[data-state="active"] {
|
|
30
30
|
color: hsl(var(--tw---token-color-primary-token-6))
|
|
31
|
-
}
|
|
31
|
+
}
|
|
32
32
|
</style>
|
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import {cn} from "../../../utils/utils";
|
|
3
|
-
import {getCtx} from "../Tabs";
|
|
4
|
-
|
|
5
|
-
let {
|
|
6
|
-
children,
|
|
7
|
-
class: className,
|
|
8
|
-
...props
|
|
9
|
-
} = $props();
|
|
10
|
-
|
|
11
|
-
let tabIndicator = $state()
|
|
12
|
-
let tabsList = $state()
|
|
13
|
-
|
|
14
|
-
function updateIndicator(button) {
|
|
15
|
-
const rect = button.getBoundingClientRect();
|
|
16
|
-
const containerRect = tabsList.getBoundingClientRect();
|
|
17
|
-
|
|
18
|
-
const left = rect.left - containerRect.left;
|
|
19
|
-
const width = rect.width;
|
|
20
|
-
|
|
21
|
-
tabIndicator.style.left = `${left}px`;
|
|
22
|
-
tabIndicator.style.width = `${width}px`;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
let context = getCtx()
|
|
27
|
-
|
|
28
|
-
$effect(() => {
|
|
29
|
-
let tabButton = tabsList?.querySelector(`button[data-value="${context.state.currentTab}"]`)
|
|
30
|
-
updateIndicator(tabButton);
|
|
31
|
-
})
|
|
32
|
-
</script>
|
|
33
|
-
|
|
34
|
-
<div bind:this={tabsList}
|
|
35
|
-
data-tabs-list
|
|
36
|
-
role="tablist"
|
|
37
|
-
data-orientation="horizontal"
|
|
38
|
-
class={cn("relative flex gap-2 items-end border-b border-neutral-token-5")}>
|
|
39
|
-
|
|
40
|
-
{@render children?.()}
|
|
41
|
-
<div bind:this={tabIndicator} class="absolute bottom-0 h-0.5 bg-primary-token-5 transition-all duration-300"></div>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {cn} from "../../../utils/utils";
|
|
3
|
+
import {getCtx} from "../Tabs";
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
children,
|
|
7
|
+
class: className,
|
|
8
|
+
...props
|
|
9
|
+
} = $props();
|
|
10
|
+
|
|
11
|
+
let tabIndicator = $state()
|
|
12
|
+
let tabsList = $state()
|
|
13
|
+
|
|
14
|
+
function updateIndicator(button) {
|
|
15
|
+
const rect = button.getBoundingClientRect();
|
|
16
|
+
const containerRect = tabsList.getBoundingClientRect();
|
|
17
|
+
|
|
18
|
+
const left = rect.left - containerRect.left;
|
|
19
|
+
const width = rect.width;
|
|
20
|
+
|
|
21
|
+
tabIndicator.style.left = `${left}px`;
|
|
22
|
+
tabIndicator.style.width = `${width}px`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
let context = getCtx()
|
|
27
|
+
|
|
28
|
+
$effect(() => {
|
|
29
|
+
let tabButton = tabsList?.querySelector(`button[data-value="${context.state.currentTab}"]`)
|
|
30
|
+
updateIndicator(tabButton);
|
|
31
|
+
})
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<div bind:this={tabsList}
|
|
35
|
+
data-tabs-list
|
|
36
|
+
role="tablist"
|
|
37
|
+
data-orientation="horizontal"
|
|
38
|
+
class={cn("relative flex gap-2 items-end border-b border-neutral-token-5")}>
|
|
39
|
+
|
|
40
|
+
{@render children?.()}
|
|
41
|
+
<div bind:this={tabIndicator} class="absolute bottom-0 h-0.5 bg-primary-token-5 transition-all duration-300"></div>
|
|
42
42
|
</div>
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import {type TeraUiContextProps} from "./TeraUiContext";
|
|
3
|
-
import {setGlobalContext} from "./global-context";
|
|
4
|
-
import {setLanguageTag} from "../../paraglide/runtime";
|
|
5
|
-
import * as m from '../../paraglide/messages
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
let {
|
|
9
|
-
children,
|
|
10
|
-
supportLanguages = ['en'],
|
|
11
|
-
language = 'en',
|
|
12
|
-
...props
|
|
13
|
-
}: TeraUiContextProps = $props();
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
setGlobalContext({
|
|
17
|
-
supportLanguages,
|
|
18
|
-
language,
|
|
19
|
-
...props
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
setLanguageTag(language)
|
|
23
|
-
console.log('setLanguageTag', language)
|
|
24
|
-
console.log('test translate', m.text_select_language())
|
|
25
|
-
|
|
26
|
-
</script>
|
|
27
|
-
|
|
28
|
-
{@render children()}
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {type TeraUiContextProps} from "./TeraUiContext";
|
|
3
|
+
import {setGlobalContext} from "./global-context";
|
|
4
|
+
import {setLanguageTag} from "../../paraglide/runtime";
|
|
5
|
+
import * as m from '../../paraglide/messages'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
let {
|
|
9
|
+
children,
|
|
10
|
+
supportLanguages = ['en'],
|
|
11
|
+
language = 'en',
|
|
12
|
+
...props
|
|
13
|
+
}: TeraUiContextProps = $props();
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
setGlobalContext({
|
|
17
|
+
supportLanguages,
|
|
18
|
+
language,
|
|
19
|
+
...props
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
setLanguageTag(language)
|
|
23
|
+
console.log('setLanguageTag', language)
|
|
24
|
+
console.log('test translate', m.text_select_language())
|
|
25
|
+
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
{@render children()}
|
|
@@ -1,89 +1,89 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import {type AutoSizeConfig, type TextAreaProps} from "./TextArea";
|
|
3
|
-
import {styles} from "./TextArea";
|
|
4
|
-
import {IconX} from "../icons";
|
|
5
|
-
|
|
6
|
-
let {
|
|
7
|
-
children,
|
|
8
|
-
class: className,
|
|
9
|
-
value = $bindable(),
|
|
10
|
-
ref = $bindable(),
|
|
11
|
-
size,
|
|
12
|
-
disabled,
|
|
13
|
-
variant = 'outlined',
|
|
14
|
-
autoSize,
|
|
15
|
-
onchange,
|
|
16
|
-
prefix,
|
|
17
|
-
rows,
|
|
18
|
-
allowClear,
|
|
19
|
-
...props
|
|
20
|
-
}: TextAreaProps = $props();
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
function createAutoSizeTextarea(node: HTMLTextAreaElement, autoSize?: AutoSizeConfig) {
|
|
24
|
-
if (!autoSize) {
|
|
25
|
-
return
|
|
26
|
-
}
|
|
27
|
-
let minRows: number | null = null
|
|
28
|
-
let maxRows: number | null = null
|
|
29
|
-
if (autoSize === true) {
|
|
30
|
-
minRows = 1
|
|
31
|
-
} else {
|
|
32
|
-
minRows = Math.max(autoSize.minRows || 0, 1)
|
|
33
|
-
maxRows = autoSize.maxRows || null
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const updateSize = () => {
|
|
38
|
-
node.style.height = 'auto';
|
|
39
|
-
const computedStyle = window.getComputedStyle(node);
|
|
40
|
-
const borderTopWidth = parseFloat(computedStyle.borderTopWidth);
|
|
41
|
-
const borderBottomWidth = parseFloat(computedStyle.borderBottomWidth);
|
|
42
|
-
const offset = borderTopWidth + borderBottomWidth;
|
|
43
|
-
const scrollHeight = node.scrollHeight + 4
|
|
44
|
-
|
|
45
|
-
const lineHeight = parseFloat(computedStyle.lineHeight);
|
|
46
|
-
const minHeight = minRows * lineHeight + offset;
|
|
47
|
-
const maxHeight = maxRows ? maxRows * lineHeight : null;
|
|
48
|
-
|
|
49
|
-
node.style.height = `${Math.max(minHeight, Math.min(scrollHeight, maxHeight ?? scrollHeight))}px`;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
$effect(() => {
|
|
53
|
-
// setup goes here
|
|
54
|
-
value
|
|
55
|
-
updateSize();
|
|
56
|
-
|
|
57
|
-
return () => {
|
|
58
|
-
// teardown goes here
|
|
59
|
-
};
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function clearText() {
|
|
64
|
-
value = ''
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
</script>
|
|
68
|
-
|
|
69
|
-
<div class="relative">
|
|
70
|
-
<textarea
|
|
71
|
-
use:createAutoSizeTextarea={autoSize}
|
|
72
|
-
onchange={onchange}
|
|
73
|
-
bind:this={ref}
|
|
74
|
-
style={autoSize ? "resize: none;" : ''}
|
|
75
|
-
class={styles({ variant, disabled , size, className, allowClear })}
|
|
76
|
-
{disabled}
|
|
77
|
-
rows={autoSize ? 1 : rows}
|
|
78
|
-
{...props}
|
|
79
|
-
bind:value
|
|
80
|
-
>
|
|
81
|
-
</textarea>
|
|
82
|
-
|
|
83
|
-
{#if allowClear && value}
|
|
84
|
-
<button onclick={clearText}
|
|
85
|
-
class="absolute top-2 right-2 bg-neutral-token-6 text-neutral-token-1 hover:bg-neutral-token-8 size-3 grid place-content-center rounded-full">
|
|
86
|
-
<IconX class="size-2.5"/>
|
|
87
|
-
</button>
|
|
88
|
-
{/if}
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {type AutoSizeConfig, type TextAreaProps} from "./TextArea";
|
|
3
|
+
import {styles} from "./TextArea";
|
|
4
|
+
import {IconX} from "../icons";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
children,
|
|
8
|
+
class: className,
|
|
9
|
+
value = $bindable(),
|
|
10
|
+
ref = $bindable(),
|
|
11
|
+
size,
|
|
12
|
+
disabled,
|
|
13
|
+
variant = 'outlined',
|
|
14
|
+
autoSize,
|
|
15
|
+
onchange,
|
|
16
|
+
prefix,
|
|
17
|
+
rows,
|
|
18
|
+
allowClear,
|
|
19
|
+
...props
|
|
20
|
+
}: TextAreaProps = $props();
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
function createAutoSizeTextarea(node: HTMLTextAreaElement, autoSize?: AutoSizeConfig) {
|
|
24
|
+
if (!autoSize) {
|
|
25
|
+
return
|
|
26
|
+
}
|
|
27
|
+
let minRows: number | null = null
|
|
28
|
+
let maxRows: number | null = null
|
|
29
|
+
if (autoSize === true) {
|
|
30
|
+
minRows = 1
|
|
31
|
+
} else {
|
|
32
|
+
minRows = Math.max(autoSize.minRows || 0, 1)
|
|
33
|
+
maxRows = autoSize.maxRows || null
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const updateSize = () => {
|
|
38
|
+
node.style.height = 'auto';
|
|
39
|
+
const computedStyle = window.getComputedStyle(node);
|
|
40
|
+
const borderTopWidth = parseFloat(computedStyle.borderTopWidth);
|
|
41
|
+
const borderBottomWidth = parseFloat(computedStyle.borderBottomWidth);
|
|
42
|
+
const offset = borderTopWidth + borderBottomWidth;
|
|
43
|
+
const scrollHeight = node.scrollHeight + 4
|
|
44
|
+
|
|
45
|
+
const lineHeight = parseFloat(computedStyle.lineHeight);
|
|
46
|
+
const minHeight = minRows * lineHeight + offset;
|
|
47
|
+
const maxHeight = maxRows ? maxRows * lineHeight : null;
|
|
48
|
+
|
|
49
|
+
node.style.height = `${Math.max(minHeight, Math.min(scrollHeight, maxHeight ?? scrollHeight))}px`;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
$effect(() => {
|
|
53
|
+
// setup goes here
|
|
54
|
+
value
|
|
55
|
+
updateSize();
|
|
56
|
+
|
|
57
|
+
return () => {
|
|
58
|
+
// teardown goes here
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function clearText() {
|
|
64
|
+
value = ''
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
</script>
|
|
68
|
+
|
|
69
|
+
<div class="relative">
|
|
70
|
+
<textarea
|
|
71
|
+
use:createAutoSizeTextarea={autoSize}
|
|
72
|
+
onchange={onchange}
|
|
73
|
+
bind:this={ref}
|
|
74
|
+
style={autoSize ? "resize: none;" : ''}
|
|
75
|
+
class={styles({ variant, disabled , size, className, allowClear })}
|
|
76
|
+
{disabled}
|
|
77
|
+
rows={autoSize ? 1 : rows}
|
|
78
|
+
{...props}
|
|
79
|
+
bind:value
|
|
80
|
+
>
|
|
81
|
+
</textarea>
|
|
82
|
+
|
|
83
|
+
{#if allowClear && value}
|
|
84
|
+
<button onclick={clearText}
|
|
85
|
+
class="absolute top-2 right-2 bg-neutral-token-6 text-neutral-token-1 hover:bg-neutral-token-8 size-3 grid place-content-center rounded-full">
|
|
86
|
+
<IconX class="size-2.5"/>
|
|
87
|
+
</button>
|
|
88
|
+
{/if}
|
|
89
89
|
</div>
|
|
@@ -1,68 +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(false)
|
|
19
|
-
</script>
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
{#if user}
|
|
23
|
-
<button class="rounded-full focus-visible:ring-0" 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>
|
|
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(false)
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
{#if user}
|
|
23
|
+
<button class="rounded-full focus-visible:ring-0" 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
68
|
{/if}
|
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export { Popover } from './components/popover';
|
|
|
14
14
|
export { PopoverResponsive } from './components/popover-responsive';
|
|
15
15
|
export { SideNavigation, SideNavigationLayout, toggleSideNavigation } from './components/side-navigation';
|
|
16
16
|
export { Slider } from './components/slider';
|
|
17
|
+
export { StarRating } from './components/star-rating';
|
|
17
18
|
export { Tabs, TabsList, TabsItem, TabsContent } from './components/tabs';
|
|
18
19
|
export { TeraUiContext } from './components/tera-ui-context';
|
|
19
20
|
export { TextArea } from './components/text-area';
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,7 @@ export { Popover } from './components/popover';
|
|
|
14
14
|
export { PopoverResponsive } from './components/popover-responsive';
|
|
15
15
|
export { SideNavigation, SideNavigationLayout, toggleSideNavigation } from './components/side-navigation';
|
|
16
16
|
export { Slider } from './components/slider';
|
|
17
|
+
export { StarRating } from './components/star-rating';
|
|
17
18
|
export { Tabs, TabsList, TabsItem, TabsContent } from './components/tabs';
|
|
18
19
|
export { TeraUiContext } from './components/tera-ui-context';
|
|
19
20
|
export { TextArea } from './components/text-area';
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
/* Light mode scrollbar styles */
|
|
2
|
-
::-webkit-scrollbar {
|
|
3
|
-
width: 8px;
|
|
4
|
-
height: 8px;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
::-webkit-scrollbar-track {
|
|
8
|
-
background: transparent; /* Transparent track */
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
::-webkit-scrollbar-thumb {
|
|
12
|
-
background-color: rgba(0, 0, 0, 0.2); /* Light mode: dark thumb */
|
|
13
|
-
border-radius: 10px;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
::-webkit-scrollbar-thumb:hover {
|
|
17
|
-
background-color: rgba(0, 0, 0, 0.4); /* Darker thumb on hover */
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/* Dark mode scrollbar styles */
|
|
21
|
-
.dark ::-webkit-scrollbar-thumb {
|
|
22
|
-
background-color: rgba(255, 255, 255, 0.2); /* Dark mode: light thumb */
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
.dark ::-webkit-scrollbar-thumb:hover {
|
|
26
|
-
background-color: rgba(255, 255, 255, 0.4); /* Lighter thumb on hover */
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/* Firefox scrollbar styling */
|
|
30
|
-
* {
|
|
31
|
-
scrollbar-width: thin;
|
|
32
|
-
scrollbar-color: rgba(0, 0, 0, 0.2) transparent;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
html.dark, .dark * {
|
|
36
|
-
scrollbar-color: rgba(255, 255, 255, 0.2) transparent;
|
|
37
|
-
}
|
|
1
|
+
/* Light mode scrollbar styles */
|
|
2
|
+
::-webkit-scrollbar {
|
|
3
|
+
width: 8px;
|
|
4
|
+
height: 8px;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
::-webkit-scrollbar-track {
|
|
8
|
+
background: transparent; /* Transparent track */
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
::-webkit-scrollbar-thumb {
|
|
12
|
+
background-color: rgba(0, 0, 0, 0.2); /* Light mode: dark thumb */
|
|
13
|
+
border-radius: 10px;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
::-webkit-scrollbar-thumb:hover {
|
|
17
|
+
background-color: rgba(0, 0, 0, 0.4); /* Darker thumb on hover */
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* Dark mode scrollbar styles */
|
|
21
|
+
.dark ::-webkit-scrollbar-thumb {
|
|
22
|
+
background-color: rgba(255, 255, 255, 0.2); /* Dark mode: light thumb */
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.dark ::-webkit-scrollbar-thumb:hover {
|
|
26
|
+
background-color: rgba(255, 255, 255, 0.4); /* Lighter thumb on hover */
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* Firefox scrollbar styling */
|
|
30
|
+
* {
|
|
31
|
+
scrollbar-width: thin;
|
|
32
|
+
scrollbar-color: rgba(0, 0, 0, 0.2) transparent;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
html.dark, .dark * {
|
|
36
|
+
scrollbar-color: rgba(255, 255, 255, 0.2) transparent;
|
|
37
|
+
}
|