tera-system-ui 0.0.1
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 +58 -0
- package/dist/components/brand-logo/BrandLogo.d.ts +71 -0
- package/dist/components/brand-logo/BrandLogo.js +18 -0
- package/dist/components/brand-logo/BrandLogo.svelte +32 -0
- package/dist/components/brand-logo/BrandLogo.svelte.d.ts +3 -0
- package/dist/components/brand-logo/index.d.ts +1 -0
- package/dist/components/brand-logo/index.js +1 -0
- package/dist/components/button/Button.d.ts +149 -0
- package/dist/components/button/Button.js +72 -0
- package/dist/components/button/Button.svelte +47 -0
- package/dist/components/button/Button.svelte.d.ts +3 -0
- package/dist/components/button/index.d.ts +1 -0
- package/dist/components/button/index.js +1 -0
- package/dist/components/dialog/Dialog.d.ts +155 -0
- package/dist/components/dialog/Dialog.js +30 -0
- package/dist/components/dialog/Dialog.svelte +154 -0
- package/dist/components/dialog/Dialog.svelte.d.ts +10 -0
- package/dist/components/dialog/index.d.ts +1 -0
- package/dist/components/dialog/index.js +1 -0
- package/dist/components/header/Header.d.ts +8 -0
- package/dist/components/header/Header.js +7 -0
- package/dist/components/header/Header.svelte +36 -0
- package/dist/components/header/Header.svelte.d.ts +4 -0
- package/dist/components/header/header.scss +20 -0
- package/dist/components/header/index.d.ts +1 -0
- package/dist/components/header/index.js +1 -0
- package/dist/components/icons/IconBook.svelte +10 -0
- package/dist/components/icons/IconBook.svelte.d.ts +4 -0
- package/dist/components/icons/IconCalculator.svelte +10 -0
- package/dist/components/icons/IconCalculator.svelte.d.ts +4 -0
- package/dist/components/icons/IconCheck.svelte +10 -0
- package/dist/components/icons/IconCheck.svelte.d.ts +4 -0
- package/dist/components/icons/IconHamburger.svelte +10 -0
- package/dist/components/icons/IconHamburger.svelte.d.ts +3 -0
- package/dist/components/icons/IconLanguage.svelte +10 -0
- package/dist/components/icons/IconLanguage.svelte.d.ts +4 -0
- package/dist/components/icons/IconMoon.svelte +10 -0
- package/dist/components/icons/IconMoon.svelte.d.ts +3 -0
- package/dist/components/icons/IconSun.svelte +10 -0
- package/dist/components/icons/IconSun.svelte.d.ts +3 -0
- package/dist/components/icons/IconTransform.svelte +10 -0
- package/dist/components/icons/IconTransform.svelte.d.ts +4 -0
- package/dist/components/icons/IconX.svelte +10 -0
- package/dist/components/icons/IconX.svelte.d.ts +4 -0
- package/dist/components/icons/Icons.d.ts +43 -0
- package/dist/components/icons/Icons.js +14 -0
- package/dist/components/icons/index.d.ts +2 -0
- package/dist/components/icons/index.js +2 -0
- package/dist/components/input/Input.svelte +14 -0
- package/dist/components/input/Input.svelte.d.ts +23 -0
- package/dist/components/input/index.d.ts +1 -0
- package/dist/components/input/index.js +1 -0
- package/dist/components/input/input.d.ts +49 -0
- package/dist/components/input/input.js +14 -0
- package/dist/components/language-picker-button/LanguagePickerButton.d.ts +8 -0
- package/dist/components/language-picker-button/LanguagePickerButton.js +7 -0
- package/dist/components/language-picker-button/LanguagePickerButton.svelte +122 -0
- package/dist/components/language-picker-button/LanguagePickerButton.svelte.d.ts +7 -0
- package/dist/components/language-picker-button/index.d.ts +1 -0
- package/dist/components/language-picker-button/index.js +1 -0
- package/dist/components/light-dark-toggle/LightDarkToggle.d.ts +8 -0
- package/dist/components/light-dark-toggle/LightDarkToggle.js +7 -0
- package/dist/components/light-dark-toggle/LightDarkToggle.svelte +36 -0
- package/dist/components/light-dark-toggle/LightDarkToggle.svelte.d.ts +3 -0
- package/dist/components/light-dark-toggle/index.d.ts +1 -0
- package/dist/components/light-dark-toggle/index.js +1 -0
- package/dist/components/side-navigation/SideNavigation.d.ts +18 -0
- package/dist/components/side-navigation/SideNavigation.js +41 -0
- package/dist/components/side-navigation/SideNavigation.svelte +93 -0
- package/dist/components/side-navigation/SideNavigation.svelte.d.ts +3 -0
- package/dist/components/side-navigation/SideNavigationItem.svelte +18 -0
- package/dist/components/side-navigation/SideNavigationItem.svelte.d.ts +7 -0
- package/dist/components/side-navigation/SideNavigationLayout.svelte +19 -0
- package/dist/components/side-navigation/SideNavigationLayout.svelte.d.ts +5 -0
- package/dist/components/side-navigation/clickOutside.d.ts +4 -0
- package/dist/components/side-navigation/clickOutside.js +14 -0
- package/dist/components/side-navigation/index.d.ts +3 -0
- package/dist/components/side-navigation/index.js +3 -0
- package/dist/components/side-navigation/sidenav.scss +149 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/utils/utils.d.ts +2 -0
- package/dist/utils/utils.js +5 -0
- package/package.json +71 -0
- package/scripts/add-component-template.js +121 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {type LanguagePickerButtonProps} from "./LanguagePickerButton";
|
|
3
|
+
import {IconLanguage} from "../icons";
|
|
4
|
+
import {Dialog} from "../dialog";
|
|
5
|
+
import IconCheck from "../icons/IconCheck.svelte";
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
children,
|
|
9
|
+
currentLangCode = 'en',
|
|
10
|
+
onLangSelect,
|
|
11
|
+
supportedLanguages = ['en'],
|
|
12
|
+
...props
|
|
13
|
+
}: LanguagePickerButtonProps & {
|
|
14
|
+
currentLangCode: string,
|
|
15
|
+
supportedLanguages: string[],
|
|
16
|
+
onLangSelect: (langCode: string) => void
|
|
17
|
+
} = $props();
|
|
18
|
+
|
|
19
|
+
const LANGUAGE_LIST = [
|
|
20
|
+
{
|
|
21
|
+
code: "en",
|
|
22
|
+
label: "English (US)",
|
|
23
|
+
flag: 'united states'
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
code: "de",
|
|
27
|
+
label: "Deutsch",
|
|
28
|
+
flag: 'germany'
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
code: "es",
|
|
32
|
+
label: "Español",
|
|
33
|
+
flag: 'spain'
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
code: "fr",
|
|
37
|
+
label: "Français",
|
|
38
|
+
flag: 'france'
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
code: "it",
|
|
42
|
+
label: "Italiano",
|
|
43
|
+
flag: 'italy'
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
code: "pt",
|
|
47
|
+
label: "Português",
|
|
48
|
+
flag: 'portugal'
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
code: "ru",
|
|
52
|
+
label: "Русский",
|
|
53
|
+
flag: 'russia'
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
code: "vi",
|
|
57
|
+
label: "Tiếng Việt",
|
|
58
|
+
flag: 'vietnam'
|
|
59
|
+
}
|
|
60
|
+
].filter(lang => supportedLanguages.includes(lang.code))
|
|
61
|
+
|
|
62
|
+
let currentLangItem = $derived(LANGUAGE_LIST.find(l => l.code === currentLangCode)!)
|
|
63
|
+
|
|
64
|
+
function getFlagUrl(flag: string) {
|
|
65
|
+
if (flag === 'spain') {
|
|
66
|
+
return `/world-flags/${flag}.png`
|
|
67
|
+
}
|
|
68
|
+
return `/world-flags/${flag}.svg`
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let openDialog = $state(false)
|
|
72
|
+
</script>
|
|
73
|
+
|
|
74
|
+
<!--add component here-->
|
|
75
|
+
<button onclick={() => {openDialog = true}}
|
|
76
|
+
class="h-8 flex items-center bg-neutral-token-4 text-neutral-token-9 rounded-full ps-2 pe-1 hover:bg-neutral-token-5 transition-all duration-element-react">
|
|
77
|
+
<IconLanguage class="size-icon-xs"/>
|
|
78
|
+
<img class="size-6 flag-img" src={getFlagUrl(currentLangItem.flag)} alt={currentLangItem.flag}>
|
|
79
|
+
</button>
|
|
80
|
+
|
|
81
|
+
<Dialog bind:open={openDialog} class="text-neutral-token-13" size="xs">
|
|
82
|
+
{#snippet header()}
|
|
83
|
+
Select language
|
|
84
|
+
{/snippet}
|
|
85
|
+
<div class="grid grid-cols-1 mx-auto gap-2">
|
|
86
|
+
{#each LANGUAGE_LIST as lang}
|
|
87
|
+
<button class="w-full flex gap-1 items-center justify-between text-start px-1 py-1 pe-2 rounded-full bg-neutral-token-3"
|
|
88
|
+
onclick={() => {
|
|
89
|
+
onLangSelect?.(lang.code)
|
|
90
|
+
openDialog = false
|
|
91
|
+
}}
|
|
92
|
+
data-selected={lang.code === currentLangCode ? '' : undefined}>
|
|
93
|
+
<div class="flex items-center gap-2">
|
|
94
|
+
<img class="size-12 flag-img" src={getFlagUrl(lang.flag)} alt={currentLangItem.flag} loading="lazy">
|
|
95
|
+
{lang.label}
|
|
96
|
+
</div>
|
|
97
|
+
<div class="check">
|
|
98
|
+
<IconCheck class="check size-icon-sm"/>
|
|
99
|
+
</div>
|
|
100
|
+
</button>
|
|
101
|
+
{/each}
|
|
102
|
+
</div>
|
|
103
|
+
</Dialog>
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
<style>button .check {
|
|
107
|
+
opacity: 0;
|
|
108
|
+
}
|
|
109
|
+
button:hover {
|
|
110
|
+
background-color: hsl(var(--tw---token-color-neutral-token-4));
|
|
111
|
+
}
|
|
112
|
+
button[data-selected] {
|
|
113
|
+
background-color: hsl(var(--tw---token-color-neutral-token-11));
|
|
114
|
+
color: hsl(var(--tw---token-color-neutral-token-1));
|
|
115
|
+
}
|
|
116
|
+
button[data-selected] .check {
|
|
117
|
+
opacity: 1;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.flag-img {
|
|
121
|
+
border-radius: 9999px;
|
|
122
|
+
}</style>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type LanguagePickerButtonProps } from "./LanguagePickerButton";
|
|
2
|
+
declare const LanguagePickerButton: import("svelte").Component<LanguagePickerButtonProps & {
|
|
3
|
+
currentLangCode: string;
|
|
4
|
+
supportedLanguages: string[];
|
|
5
|
+
onLangSelect: (langCode: string) => void;
|
|
6
|
+
}, {}, "">;
|
|
7
|
+
export default LanguagePickerButton;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as LanguagePickerButton } from './LanguagePickerButton.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as LanguagePickerButton } from './LanguagePickerButton.svelte';
|
|
@@ -0,0 +1,8 @@
|
|
|
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 LightDarkToggleVariants = VariantProps<typeof styles>;
|
|
4
|
+
export interface LightDarkToggleProps extends LightDarkToggleVariants {
|
|
5
|
+
children?: any;
|
|
6
|
+
class?: string;
|
|
7
|
+
}
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {type LightDarkToggleProps} from "./LightDarkToggle";
|
|
3
|
+
import {Button} from "../button";
|
|
4
|
+
import IconSun from "../icons/IconSun.svelte";
|
|
5
|
+
import IconMoon from "../icons/IconMoon.svelte";
|
|
6
|
+
|
|
7
|
+
let {children, ...props}: LightDarkToggleProps = $props();
|
|
8
|
+
|
|
9
|
+
$effect(() => {
|
|
10
|
+
const htmlElement = document.documentElement;
|
|
11
|
+
// Check for saved theme preference
|
|
12
|
+
const currentTheme = localStorage.getItem('theme');
|
|
13
|
+
if (currentTheme === 'dark') {
|
|
14
|
+
htmlElement.classList.add('dark');
|
|
15
|
+
} else {
|
|
16
|
+
htmlElement.classList.remove('dark');
|
|
17
|
+
}
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
function toggleLightDarkTheme() {
|
|
21
|
+
const htmlElement = document.documentElement;
|
|
22
|
+
|
|
23
|
+
htmlElement.classList.toggle('dark');
|
|
24
|
+
const theme = htmlElement.classList.contains('dark') ? 'dark' : 'light';
|
|
25
|
+
localStorage.setItem('theme', theme);
|
|
26
|
+
}
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<!--add component here-->
|
|
30
|
+
<Button variant="ghost" icon
|
|
31
|
+
onclick={toggleLightDarkTheme}>
|
|
32
|
+
<!-- Sun icon, animates out when in dark mode -->
|
|
33
|
+
<IconSun class="icon-sun dark:hidden"/>
|
|
34
|
+
<!-- Moon icon, animates in when in dark mode -->
|
|
35
|
+
<IconMoon class="icon-moon hidden dark:block"/>
|
|
36
|
+
</Button>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as LightDarkToggle } from './LightDarkToggle.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as LightDarkToggle } from './LightDarkToggle.svelte';
|
|
@@ -0,0 +1,18 @@
|
|
|
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 SideNavigationVariants = VariantProps<typeof styles>;
|
|
4
|
+
export interface SideNavigationProps extends SideNavigationVariants {
|
|
5
|
+
children?: any;
|
|
6
|
+
class?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const BEAK_POINTS: {
|
|
9
|
+
sm: number;
|
|
10
|
+
md: number;
|
|
11
|
+
lg: number;
|
|
12
|
+
xl: number;
|
|
13
|
+
};
|
|
14
|
+
export declare const mainLayout: () => HTMLElement | null;
|
|
15
|
+
export declare const getSideNavState: () => string | undefined;
|
|
16
|
+
export declare const setSideNavState: (state: any) => void;
|
|
17
|
+
export declare function toggleSideNavigation(): void;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { tv } from "tailwind-variants";
|
|
2
|
+
export const styles = tv({
|
|
3
|
+
base: '',
|
|
4
|
+
variants: {},
|
|
5
|
+
compoundVariants: [],
|
|
6
|
+
defaultVariants: {},
|
|
7
|
+
});
|
|
8
|
+
export const BEAK_POINTS = {
|
|
9
|
+
sm: 640,
|
|
10
|
+
md: 768,
|
|
11
|
+
lg: 1024,
|
|
12
|
+
xl: 1280,
|
|
13
|
+
};
|
|
14
|
+
export const mainLayout = () => document?.getElementById('side-nav_main-layout');
|
|
15
|
+
export const getSideNavState = () => {
|
|
16
|
+
return mainLayout()?.getAttribute('data-side-nav-state') || undefined;
|
|
17
|
+
};
|
|
18
|
+
export const setSideNavState = (state) => {
|
|
19
|
+
console.log(mainLayout());
|
|
20
|
+
if (state !== undefined) {
|
|
21
|
+
mainLayout()?.setAttribute('data-side-nav-state', state);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
mainLayout()?.removeAttribute('data-side-nav-state');
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
export function toggleSideNavigation() {
|
|
28
|
+
let screenWidth = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
|
|
29
|
+
let currentSideNavState = getSideNavState();
|
|
30
|
+
let state;
|
|
31
|
+
if (screenWidth < BEAK_POINTS.md) {
|
|
32
|
+
state = currentSideNavState == undefined ? "expand" : undefined;
|
|
33
|
+
}
|
|
34
|
+
else if (screenWidth >= BEAK_POINTS.md && screenWidth < BEAK_POINTS.xl) {
|
|
35
|
+
state = currentSideNavState == undefined ? "expand" : undefined;
|
|
36
|
+
}
|
|
37
|
+
else if (screenWidth >= BEAK_POINTS.xl) {
|
|
38
|
+
state = currentSideNavState == undefined ? "compact" : undefined;
|
|
39
|
+
}
|
|
40
|
+
setSideNavState(state);
|
|
41
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
BEAK_POINTS,
|
|
4
|
+
mainLayout,
|
|
5
|
+
setSideNavState,
|
|
6
|
+
type SideNavigationProps,
|
|
7
|
+
toggleSideNavigation
|
|
8
|
+
} from "./SideNavigation";
|
|
9
|
+
import {clickOutside} from "./clickOutside"
|
|
10
|
+
import {Button} from "../button";
|
|
11
|
+
import {IconHamburger} from "../icons";
|
|
12
|
+
import {BrandLogo} from "../brand-logo";
|
|
13
|
+
import SideNavItem from "./SideNavigationItem.svelte";
|
|
14
|
+
import IconBook from "../icons/IconBook.svelte";
|
|
15
|
+
import IconTransform from "../icons/IconTransform.svelte";
|
|
16
|
+
import IconCalculator from "../icons/IconCalculator.svelte";
|
|
17
|
+
import {LightDarkToggle} from "../light-dark-toggle";
|
|
18
|
+
|
|
19
|
+
let {children, ...props}: SideNavigationProps = $props();
|
|
20
|
+
|
|
21
|
+
let temporaryExpand: any = undefined
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
function handleClickOutside() {
|
|
25
|
+
let screenWidth = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0)
|
|
26
|
+
if (screenWidth < BEAK_POINTS.md) {
|
|
27
|
+
setSideNavState(undefined)
|
|
28
|
+
} else if (screenWidth >= BEAK_POINTS.md && screenWidth < BEAK_POINTS.xl) {
|
|
29
|
+
setSideNavState(undefined)
|
|
30
|
+
} else if (screenWidth >= BEAK_POINTS.xl) {
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function handleHover(isHover: boolean) {
|
|
36
|
+
temporaryExpand = isHover ? true : undefined
|
|
37
|
+
|
|
38
|
+
if (temporaryExpand) {
|
|
39
|
+
mainLayout()?.setAttribute('data-side-nav-temporary-expand', temporaryExpand)
|
|
40
|
+
} else {
|
|
41
|
+
mainLayout()?.removeAttribute('data-side-nav-temporary-expand')
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<nav class="side-nav_main-side-bar grid grid-rows-[auto_1fr_auto]"
|
|
48
|
+
use:clickOutside
|
|
49
|
+
onclick_outside={handleClickOutside}
|
|
50
|
+
>
|
|
51
|
+
<div class="flex mt-2 gap-1 items-center">
|
|
52
|
+
<Button variant="ghost" class="ring-0 focus:ring-0"
|
|
53
|
+
onclick={toggleSideNavigation}
|
|
54
|
+
>
|
|
55
|
+
<IconHamburger/>
|
|
56
|
+
</Button>
|
|
57
|
+
<div class="sm-hidden">
|
|
58
|
+
<BrandLogo/>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
<ul class="mt-12"
|
|
62
|
+
onmouseenter={() => {
|
|
63
|
+
handleHover(true)
|
|
64
|
+
}}
|
|
65
|
+
onmouseleave={() => {
|
|
66
|
+
handleHover(false)
|
|
67
|
+
}}
|
|
68
|
+
>
|
|
69
|
+
<SideNavItem href="/calculator" class="selected">
|
|
70
|
+
{#snippet icon()}
|
|
71
|
+
<IconCalculator/>
|
|
72
|
+
{/snippet}
|
|
73
|
+
CalcES Scientific Calculator
|
|
74
|
+
</SideNavItem>
|
|
75
|
+
<SideNavItem href="/convert" class="">
|
|
76
|
+
{#snippet icon()}
|
|
77
|
+
<IconTransform/>
|
|
78
|
+
{/snippet}
|
|
79
|
+
Unit Converter
|
|
80
|
+
</SideNavItem>
|
|
81
|
+
<SideNavItem href="/docs/calculator-usages/calces">
|
|
82
|
+
{#snippet icon()}
|
|
83
|
+
<IconBook/>
|
|
84
|
+
{/snippet}
|
|
85
|
+
CalcES Documentation
|
|
86
|
+
</SideNavItem>
|
|
87
|
+
</ul>
|
|
88
|
+
<div>
|
|
89
|
+
<div class="w-[3rem] mb-8 flex justify-center">
|
|
90
|
+
<LightDarkToggle/>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
</nav>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
const {class: className, href, children, icon} = $props()
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<li class="{className + ' side-nav_item'}">
|
|
6
|
+
<a href="{href || '#'}" class="">
|
|
7
|
+
<div class="min-w-icon-sm z-10">
|
|
8
|
+
{@render icon?.()}
|
|
9
|
+
</div>
|
|
10
|
+
<div class="sm-hidden z-10">
|
|
11
|
+
{@render children?.()}
|
|
12
|
+
</div>
|
|
13
|
+
</a>
|
|
14
|
+
</li>
|
|
15
|
+
|
|
16
|
+
<style>
|
|
17
|
+
|
|
18
|
+
</style>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {SideNavigation} from "./";
|
|
3
|
+
import './sidenav.scss'
|
|
4
|
+
|
|
5
|
+
let {children} = $props()
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<main
|
|
9
|
+
id="side-nav_main-layout"
|
|
10
|
+
class="side-nav_main-layout relative"
|
|
11
|
+
data-side-nav-state="compact"
|
|
12
|
+
>
|
|
13
|
+
<SideNavigation/>
|
|
14
|
+
|
|
15
|
+
<section class="side-nav_main-content">
|
|
16
|
+
{@render children?.()}
|
|
17
|
+
</section>
|
|
18
|
+
</main>
|
|
19
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Dispatch event on click outside of node */
|
|
2
|
+
export function clickOutside(node) {
|
|
3
|
+
const handleClick = (event) => {
|
|
4
|
+
if (node && !node.contains(event.target) && !event.defaultPrevented) {
|
|
5
|
+
node.dispatchEvent(new CustomEvent('click_outside', node));
|
|
6
|
+
}
|
|
7
|
+
};
|
|
8
|
+
document.addEventListener('click', handleClick, true);
|
|
9
|
+
return {
|
|
10
|
+
destroy() {
|
|
11
|
+
document.removeEventListener('click', handleClick, true);
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--sidebar-width: 0;
|
|
3
|
+
--sidebar-transition-duration: 0.2s;
|
|
4
|
+
--sidebar-main-margin-left: 0;
|
|
5
|
+
--sidebar-border-width: 0;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.side-nav_main-layout {
|
|
9
|
+
transition: padding-left var(--sidebar-transition-duration);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.side-nav_main-side-bar {
|
|
13
|
+
container-type: inline-size;
|
|
14
|
+
z-index: 50;
|
|
15
|
+
width: var(--sidebar-width);
|
|
16
|
+
overflow-x: hidden;
|
|
17
|
+
border-right: var(--sidebar-border-width) solid theme('colors.neutral.token.5');
|
|
18
|
+
height: 100dvh;
|
|
19
|
+
position: fixed;
|
|
20
|
+
top: 0;
|
|
21
|
+
left: 0;
|
|
22
|
+
bottom: 0;
|
|
23
|
+
|
|
24
|
+
transition: width var(--sidebar-transition-duration);
|
|
25
|
+
background: theme('colors.neutral.token.1');
|
|
26
|
+
|
|
27
|
+
ul {
|
|
28
|
+
width: var(--sidebar-width);
|
|
29
|
+
transition: width var(--sidebar-transition-duration);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
.sm-hidden {
|
|
36
|
+
opacity: 0;
|
|
37
|
+
transition: opacity var(--sidebar-transition-duration);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@container (min-width: 3rem) {
|
|
41
|
+
.sm-hidden {
|
|
42
|
+
opacity: 1;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.side-nav_main-content {
|
|
47
|
+
margin-left: var(--sidebar-main-margin-left);
|
|
48
|
+
transition: margin-left var(--sidebar-transition-duration);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
.side-nav_main-layout {
|
|
53
|
+
&[data-side-nav-state="expand"], &[data-side-nav-temporary-expand="true"] {
|
|
54
|
+
--sidebar-width: 16.5rem;
|
|
55
|
+
--sidebar-border-width: 1px;
|
|
56
|
+
.header-brand-logo {
|
|
57
|
+
display: none;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@media (min-width: theme('screens.md')) {
|
|
63
|
+
:root {
|
|
64
|
+
--sidebar-main-margin-left: 3rem;
|
|
65
|
+
--sidebar-border-width: 1px;
|
|
66
|
+
--sidebar-width: 3rem;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@media (min-width: theme('screens.xl')) {
|
|
71
|
+
:root {
|
|
72
|
+
--sidebar-main-margin-left: var(--sidebar-width);
|
|
73
|
+
--sidebar-width: 16.5rem;
|
|
74
|
+
}
|
|
75
|
+
.header-brand-logo {
|
|
76
|
+
display: none;
|
|
77
|
+
}
|
|
78
|
+
.side-nav_main-layout {
|
|
79
|
+
&[data-side-nav-state="compact"] {
|
|
80
|
+
--sidebar-main-margin-left: 3rem;
|
|
81
|
+
--sidebar-width: 3rem;
|
|
82
|
+
.header-brand-logo {
|
|
83
|
+
display: block;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
&[data-side-nav-temporary-expand="true"] {
|
|
88
|
+
--sidebar-width: 16.5rem;
|
|
89
|
+
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
.side-nav_item {
|
|
96
|
+
color: theme('colors.neutral.token.13');
|
|
97
|
+
|
|
98
|
+
a {
|
|
99
|
+
display: flex;
|
|
100
|
+
gap: 0.5rem;
|
|
101
|
+
align-items: center;
|
|
102
|
+
width: 100%;
|
|
103
|
+
position: relative;
|
|
104
|
+
white-space: nowrap;
|
|
105
|
+
@apply px-3 py-3 font-semibold;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
svg {
|
|
109
|
+
&.icon {
|
|
110
|
+
min-width: 24px;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
&.selected a {
|
|
115
|
+
//background-color: theme('colors.neutral.token.11');
|
|
116
|
+
color: theme('colors.neutral.token.1');
|
|
117
|
+
//@apply rounded-full;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
&.selected {
|
|
121
|
+
a::after {
|
|
122
|
+
content: '';
|
|
123
|
+
position: absolute;
|
|
124
|
+
inset-inline: 0.25rem;
|
|
125
|
+
inset-block: 0.2rem;
|
|
126
|
+
background: theme('colors.neutral.token.11');
|
|
127
|
+
border-radius: theme('borderRadius.DEFAULT');
|
|
128
|
+
z-index: 0;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
//&.selected {
|
|
133
|
+
// a::after {
|
|
134
|
+
// content: '';
|
|
135
|
+
// position: absolute;
|
|
136
|
+
// left: 0;
|
|
137
|
+
// top: 0;
|
|
138
|
+
// bottom: 0;
|
|
139
|
+
// width: 4px;
|
|
140
|
+
// height: 100%;
|
|
141
|
+
// background: theme('colors.primary.token.4');
|
|
142
|
+
// border-radius: 4px 0 0 4px;
|
|
143
|
+
// }
|
|
144
|
+
//}
|
|
145
|
+
|
|
146
|
+
&:hover {
|
|
147
|
+
background-color: theme('colors.neutral.token.3');
|
|
148
|
+
}
|
|
149
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.js
ADDED