negodesign 0.0.26 → 0.0.28

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 (115) hide show
  1. package/dist/assets/placeholder-company.png +0 -0
  2. package/dist/assets/placeholder-image.png +0 -0
  3. package/dist/components/core/breadcrumb/breadcrumb-list.svelte +31 -31
  4. package/dist/components/core/button/ButtonBack.svelte +18 -18
  5. package/dist/components/core/button/ButtonLogin.svelte +15 -15
  6. package/dist/components/core/button/ButtonLoginWith.svelte +57 -57
  7. package/dist/components/core/button/ButtonSend.svelte +15 -15
  8. package/dist/components/core/card/highlight/01/CardHighlight01.svelte +110 -91
  9. package/dist/components/core/card/highlight/02/CardHighlight02.svelte +108 -93
  10. package/dist/components/core/card/highlight/CardHighlight.svelte +22 -22
  11. package/dist/components/core/card/highlight/data.js +4 -1
  12. package/dist/components/core/card/media/01/CardMedia01.svelte +111 -111
  13. package/dist/components/core/card/media/02/CardMedia02.svelte +110 -110
  14. package/dist/components/core/card/media/CardMedia.svelte +17 -17
  15. package/dist/components/core/card/profile/01/CardProfile01.svelte +98 -98
  16. package/dist/components/core/card/profile/02/CardProfile02.svelte +98 -98
  17. package/dist/components/core/card/profile/CardProfile.svelte +17 -17
  18. package/dist/components/core/card/promotion/CardPromotion.svelte +133 -112
  19. package/dist/components/core/card/shared/CardButton.svelte +30 -30
  20. package/dist/components/core/card/shared/CardCart.svelte +36 -36
  21. package/dist/components/core/card/shared/CardDescription.svelte +38 -38
  22. package/dist/components/core/card/shared/CardFavorite.svelte +33 -33
  23. package/dist/components/core/card/shared/CardStarRating.svelte +20 -20
  24. package/dist/components/core/card/shared/CardStartPrice.svelte +32 -34
  25. package/dist/components/core/card/shared/CardTags.svelte +70 -73
  26. package/dist/components/core/card/shared/CardThumbnailVideo.svelte +169 -169
  27. package/dist/components/core/card/shared/TruncatableText.svelte +55 -55
  28. package/dist/components/core/carousel/badge/ui/CarouselBadge.svelte +82 -83
  29. package/dist/components/core/carousel/hero/CarouselHero.svelte +158 -158
  30. package/dist/components/core/carousel/highlights/ui/CarouselHighlights.svelte +65 -63
  31. package/dist/components/core/carousel/promotion/ui/CarouselPromotion.svelte +64 -64
  32. package/dist/components/core/carousel/shared/ui/CarouselHeader.svelte +55 -55
  33. package/dist/components/core/datatable/ui/DataTableActions.svelte +28 -28
  34. package/dist/components/core/datatable/ui/DataTableCheckbox.svelte +22 -22
  35. package/dist/components/core/datatable/ui/DataTableContent.svelte +59 -59
  36. package/dist/components/core/datatable/ui/DataTableCore.svelte +151 -151
  37. package/dist/components/core/datatable/ui/DataTableDragHandle.svelte +8 -8
  38. package/dist/components/core/datatable/ui/DataTableListFilter.svelte +59 -59
  39. package/dist/components/core/datatable/ui/DataTableListPagination.svelte +35 -35
  40. package/dist/components/core/form/ui/input-base.svelte +81 -81
  41. package/dist/components/core/form/ui/input-email-or-phone.svelte +23 -23
  42. package/dist/components/core/form/ui/input-email.svelte +23 -23
  43. package/dist/components/core/form/ui/input-password-confirm.svelte +23 -23
  44. package/dist/components/core/form/ui/input-password.svelte +23 -23
  45. package/dist/components/core/form/ui/input-phone.svelte +33 -33
  46. package/dist/components/core/form/ui/input-username.svelte +22 -22
  47. package/dist/components/core/hero/SimpleHero.svelte +65 -65
  48. package/dist/components/core/label/LabelOr.svelte +25 -25
  49. package/dist/components/core/link/link-forget-password.svelte +12 -12
  50. package/dist/components/core/link/link-privacy-polity.svelte +12 -12
  51. package/dist/components/core/link/link-terms-of-service.svelte +12 -12
  52. package/dist/components/core/nav/ui/menu-links.svelte +27 -27
  53. package/dist/components/core/nav/ui/mobile/nav-menu-drawer.svelte +85 -85
  54. package/dist/components/core/nav/ui/nav-menu-bottom-sidebar.svelte +33 -33
  55. package/dist/components/core/nav/ui/nav-menu-sidebar.svelte +97 -97
  56. package/dist/components/core/nav/ui/nav-menu-top-bar-sidebar.svelte +103 -103
  57. package/dist/components/core/nav/ui/nav-menu.svelte +106 -106
  58. package/dist/components/core/panel/CarouselSlot.svelte +63 -63
  59. package/dist/components/core/panel/LeftHero.svelte +116 -116
  60. package/dist/components/core/search/SearchInput.svelte +32 -32
  61. package/dist/components/core/search/shared/SearchInputCore.svelte +66 -66
  62. package/dist/components/core/sidebar/MenuBarSidebar.svelte +70 -70
  63. package/dist/components/core/tabs/ui/tab-underline.svelte +43 -43
  64. package/dist/components/pages/admin/01/ui/AdminContent.svelte +14 -14
  65. package/dist/components/pages/admin/01/ui/AdminPanel.svelte +46 -46
  66. package/dist/components/pages/security/login/01/ui/FormRegister.svelte +28 -28
  67. package/dist/components/pages/security/login/01/ui/LoginCard.svelte +107 -107
  68. package/dist/components/pages/security/login/PageLogin.svelte +22 -22
  69. package/dist/components/ui/badge/badge.svelte +49 -49
  70. package/dist/components/ui/button/button.svelte +82 -82
  71. package/dist/components/ui/chart/chart-container.svelte +80 -80
  72. package/dist/components/ui/chart/chart-style.svelte +37 -37
  73. package/dist/components/ui/chart/chart-tooltip.svelte +184 -184
  74. package/dist/components/ui/checkbox/checkbox.svelte +40 -40
  75. package/dist/components/ui/data-table/flex-render.svelte +40 -40
  76. package/dist/components/ui/drawer/drawer-close.svelte +7 -7
  77. package/dist/components/ui/drawer/drawer-content.svelte +33 -33
  78. package/dist/components/ui/drawer/drawer-description.svelte +17 -17
  79. package/dist/components/ui/drawer/drawer-footer.svelte +20 -20
  80. package/dist/components/ui/drawer/drawer-header.svelte +20 -20
  81. package/dist/components/ui/drawer/drawer-nested.svelte +12 -12
  82. package/dist/components/ui/drawer/drawer-overlay.svelte +17 -17
  83. package/dist/components/ui/drawer/drawer-portal.svelte +7 -7
  84. package/dist/components/ui/drawer/drawer-title.svelte +17 -17
  85. package/dist/components/ui/drawer/drawer-trigger.svelte +7 -7
  86. package/dist/components/ui/drawer/drawer.svelte +12 -12
  87. package/dist/components/ui/select/select-content.svelte +45 -45
  88. package/dist/components/ui/select/select-group-heading.svelte +21 -21
  89. package/dist/components/ui/select/select-group.svelte +17 -17
  90. package/dist/components/ui/select/select-item.svelte +41 -41
  91. package/dist/components/ui/select/select-label.svelte +20 -20
  92. package/dist/components/ui/select/select-portal.svelte +7 -7
  93. package/dist/components/ui/select/select-scroll-down-button.svelte +21 -21
  94. package/dist/components/ui/select/select-scroll-up-button.svelte +21 -21
  95. package/dist/components/ui/select/select-separator.svelte +18 -18
  96. package/dist/components/ui/select/select-trigger.svelte +30 -30
  97. package/dist/components/ui/select/select.svelte +11 -11
  98. package/dist/components/ui/sidebar/sidebar-menu-sub-button.svelte +39 -39
  99. package/dist/components/ui/star-rating/star-rating-star.svelte +41 -41
  100. package/dist/components/ui/star-rating/star-rating.svelte +20 -20
  101. package/dist/components/ui/table/table-body.svelte +15 -15
  102. package/dist/components/ui/table/table-caption.svelte +20 -20
  103. package/dist/components/ui/table/table-cell.svelte +15 -15
  104. package/dist/components/ui/table/table-footer.svelte +20 -20
  105. package/dist/components/ui/table/table-head.svelte +15 -15
  106. package/dist/components/ui/table/table-header.svelte +20 -20
  107. package/dist/components/ui/table/table-row.svelte +15 -15
  108. package/dist/components/ui/table/table.svelte +17 -17
  109. package/dist/components/ui/tabs/tabs-content.svelte +17 -17
  110. package/dist/components/ui/tabs/tabs-list.svelte +40 -40
  111. package/dist/components/ui/tabs/tabs-trigger.svelte +23 -23
  112. package/dist/components/ui/tabs/tabs.svelte +19 -19
  113. package/dist/globals.css +8 -38
  114. package/dist/styles/globals.css +149 -149
  115. package/package.json +113 -113
@@ -1,12 +1,12 @@
1
- <script lang="ts">
2
- import { t } from "../../../i18n";
3
- import type { HTMLAnchorAttributes } from "svelte/elements";
4
-
5
- type Props = HTMLAnchorAttributes;
6
-
7
- let { ...restProps }: Props = $props();
8
- </script>
9
-
10
- <a {...restProps} class="text-xs text-slate-500 hover:text-slate-800 z-10">
11
- {$t("link.forget.password")}!
12
- </a>
1
+ <script lang="ts">
2
+ import { t } from "../../../i18n";
3
+ import type { HTMLAnchorAttributes } from "svelte/elements";
4
+
5
+ type Props = HTMLAnchorAttributes;
6
+
7
+ let { ...restProps }: Props = $props();
8
+ </script>
9
+
10
+ <a {...restProps} class="text-xs text-slate-500 hover:text-slate-800 z-10">
11
+ {$t("link.forget.password")}!
12
+ </a>
@@ -1,12 +1,12 @@
1
- <script lang="ts">
2
- import { t } from "../../../i18n";
3
- import type { HTMLAnchorAttributes } from "svelte/elements";
4
-
5
- type Props = HTMLAnchorAttributes;
6
-
7
- let { ...restProps }: Props = $props();
8
- </script>
9
-
10
- <a {...restProps} class="text-xs text-slate-500 hover:text-slate-800 z-10">
11
- {$t("link.privacy-policy.label")}
12
- </a>
1
+ <script lang="ts">
2
+ import { t } from "../../../i18n";
3
+ import type { HTMLAnchorAttributes } from "svelte/elements";
4
+
5
+ type Props = HTMLAnchorAttributes;
6
+
7
+ let { ...restProps }: Props = $props();
8
+ </script>
9
+
10
+ <a {...restProps} class="text-xs text-slate-500 hover:text-slate-800 z-10">
11
+ {$t("link.privacy-policy.label")}
12
+ </a>
@@ -1,12 +1,12 @@
1
- <script lang="ts">
2
- import { t } from "../../../i18n";
3
- import type { HTMLAnchorAttributes } from "svelte/elements";
4
-
5
- type Props = HTMLAnchorAttributes;
6
-
7
- let { ...restProps }: Props = $props();
8
- </script>
9
-
10
- <a {...restProps} class="text-xs text-slate-500 hover:text-slate-800 z-10">
11
- {$t("link.terms-of-service.label")}
12
- </a>
1
+ <script lang="ts">
2
+ import { t } from "../../../i18n";
3
+ import type { HTMLAnchorAttributes } from "svelte/elements";
4
+
5
+ type Props = HTMLAnchorAttributes;
6
+
7
+ let { ...restProps }: Props = $props();
8
+ </script>
9
+
10
+ <a {...restProps} class="text-xs text-slate-500 hover:text-slate-800 z-10">
11
+ {$t("link.terms-of-service.label")}
12
+ </a>
@@ -1,28 +1,28 @@
1
- <script lang="ts">
2
- import { HugeiconsIcon } from "@hugeicons/svelte";
3
- import type { NavMenuLinksProps } from "../data/nav-menu";
4
-
5
- type Props = {
6
- links: NavMenuLinksProps[];
7
- linkClass?: string;
8
- groupClass?: string;
9
- orientation?: "horizontal" | "vertical";
10
- };
11
-
12
- let { links, linkClass, groupClass, orientation }: Props = $props();
13
- </script>
14
- <ul class={`flex ${orientation === "vertical" ? "flex-col" : "items-center"} gap-2 md:gap-5 lg:gap-15 ${groupClass}`}>
15
- {#each links as item (item.label)}
16
- <li>
17
- <a
18
- class={`flex items-center gap-1 ${linkClass}`}
19
- href={item.url || "#"}
20
- >
21
- {#if item.icon}
22
- <HugeiconsIcon icon={item.icon} size={15} />
23
- {/if}
24
- {item.label}
25
- </a>
26
- </li>
27
- {/each}
1
+ <script lang="ts">
2
+ import { HugeiconsIcon } from "@hugeicons/svelte";
3
+ import type { NavMenuLinksProps } from "../data/nav-menu";
4
+
5
+ type Props = {
6
+ links: NavMenuLinksProps[];
7
+ linkClass?: string;
8
+ groupClass?: string;
9
+ orientation?: "horizontal" | "vertical";
10
+ };
11
+
12
+ let { links, linkClass, groupClass, orientation }: Props = $props();
13
+ </script>
14
+ <ul class={`flex ${orientation === "vertical" ? "flex-col" : "items-center"} gap-2 md:gap-5 lg:gap-15 ${groupClass}`}>
15
+ {#each links as item (item.label)}
16
+ <li>
17
+ <a
18
+ class={`flex items-center gap-1 ${linkClass}`}
19
+ href={item.url || "#"}
20
+ >
21
+ {#if item.icon}
22
+ <HugeiconsIcon icon={item.icon} size={15} />
23
+ {/if}
24
+ {item.label}
25
+ </a>
26
+ </li>
27
+ {/each}
28
28
  </ul>
@@ -1,85 +1,85 @@
1
- <script lang="ts">
2
- import * as Drawer from "../../../../ui/drawer/index.js";
3
- import { Button } from "../../../../ui/button/index.js";
4
- import type { NavMenuLinksProps } from "../../data/nav-menu";
5
- import { buttonVariants } from "../../../../ui/button/index.js";
6
- import { cn } from "../../../../../utils.js";
7
- import { HugeiconsIcon } from "@hugeicons/svelte";
8
- import { Login03Icon, Menu, User03Icon } from "@hugeicons/core-free-icons";
9
- import MenuLinks from "../menu-links.svelte";
10
- import LightSwitch from "../../../../ui/light-switch/light-switch.svelte";
11
- import LanguageSwitcher from "../../../../ui/language-switcher/language-switcher.svelte";
12
- import { t } from "../../../../../i18n";
13
-
14
- type Props = {
15
- links: NavMenuLinksProps[];
16
- onclickButtonLogin?: () => void;
17
- onclickButtonRegister?: () => void;
18
- };
19
-
20
- const { links, onclickButtonLogin, onclickButtonRegister }: Props =
21
- $props();
22
- </script>
23
-
24
- <div class="flex flex-wrap gap-2">
25
- <Drawer.Root direction="right">
26
- <Drawer.Trigger
27
- class={cn(buttonVariants({ variant: "outline" }), "capitalize")}
28
- >
29
- <HugeiconsIcon icon={Menu} />
30
- </Drawer.Trigger>
31
- <Drawer.Content
32
- class="data-[vaul-drawer-direction=bottom]:max-h-[50vh] data-[vaul-drawer-direction=top]:max-h-[50vh]"
33
- >
34
- <Drawer.Header>
35
- <Drawer.Title>{$t("label.menu")}</Drawer.Title>
36
- <Drawer.Description>
37
- {$t("label.navigation.text")}
38
- </Drawer.Description>
39
- </Drawer.Header>
40
- <div class="no-scrollbar overflow-y-auto px-4">
41
- <nav>
42
- <div class="mt-5 mb-4 font-semibold">{$t("label.navigation")}</div>
43
- <MenuLinks
44
- {links}
45
- groupClass="space-y-3"
46
- orientation="vertical"
47
- />
48
- </nav>
49
-
50
- <div class="mt-5">
51
- <div class="mt-5 mb-4 font-semibold">{$t("label.action")}</div>
52
- <section >
53
- {#if onclickButtonRegister}
54
- <Button
55
- variant="outline"
56
- onclick={onclickButtonRegister}
57
- >
58
- <HugeiconsIcon icon={User03Icon} />
59
- {$t("label.register")}
60
- </Button>
61
- {/if}
62
- {#if onclickButtonLogin}
63
- <Button
64
- variant="outline"
65
- onclick={onclickButtonLogin}
66
- >
67
- <HugeiconsIcon icon={Login03Icon} />
68
- {$t("label.login")}
69
- </Button>
70
- {/if}
71
- </section>
72
- </div>
73
- </div>
74
- <Drawer.Footer>
75
- <div class="flex justify-center gap-5 py-5">
76
- <LightSwitch />
77
- <LanguageSwitcher />
78
- </div>
79
- <Drawer.Close class={buttonVariants({ variant: "outline" })}>
80
- {$t("label.close")}
81
- </Drawer.Close>
82
- </Drawer.Footer>
83
- </Drawer.Content>
84
- </Drawer.Root>
85
- </div>
1
+ <script lang="ts">
2
+ import * as Drawer from "../../../../ui/drawer/index.js";
3
+ import { Button } from "../../../../ui/button/index.js";
4
+ import type { NavMenuLinksProps } from "../../data/nav-menu";
5
+ import { buttonVariants } from "../../../../ui/button/index.js";
6
+ import { cn } from "../../../../../utils.js";
7
+ import { HugeiconsIcon } from "@hugeicons/svelte";
8
+ import { Login03Icon, Menu, User03Icon } from "@hugeicons/core-free-icons";
9
+ import MenuLinks from "../menu-links.svelte";
10
+ import LightSwitch from "../../../../ui/light-switch/light-switch.svelte";
11
+ import LanguageSwitcher from "../../../../ui/language-switcher/language-switcher.svelte";
12
+ import { t } from "../../../../../i18n";
13
+
14
+ type Props = {
15
+ links: NavMenuLinksProps[];
16
+ onclickButtonLogin?: () => void;
17
+ onclickButtonRegister?: () => void;
18
+ };
19
+
20
+ const { links, onclickButtonLogin, onclickButtonRegister }: Props =
21
+ $props();
22
+ </script>
23
+
24
+ <div class="flex flex-wrap gap-2">
25
+ <Drawer.Root direction="right">
26
+ <Drawer.Trigger
27
+ class={cn(buttonVariants({ variant: "outline" }), "capitalize")}
28
+ >
29
+ <HugeiconsIcon icon={Menu} />
30
+ </Drawer.Trigger>
31
+ <Drawer.Content
32
+ class="data-[vaul-drawer-direction=bottom]:max-h-[50vh] data-[vaul-drawer-direction=top]:max-h-[50vh]"
33
+ >
34
+ <Drawer.Header>
35
+ <Drawer.Title>{$t("label.menu")}</Drawer.Title>
36
+ <Drawer.Description>
37
+ {$t("label.navigation.text")}
38
+ </Drawer.Description>
39
+ </Drawer.Header>
40
+ <div class="no-scrollbar overflow-y-auto px-4">
41
+ <nav>
42
+ <div class="mt-5 mb-4 font-semibold">{$t("label.navigation")}</div>
43
+ <MenuLinks
44
+ {links}
45
+ groupClass="space-y-3"
46
+ orientation="vertical"
47
+ />
48
+ </nav>
49
+
50
+ <div class="mt-5">
51
+ <div class="mt-5 mb-4 font-semibold">{$t("label.action")}</div>
52
+ <section >
53
+ {#if onclickButtonRegister}
54
+ <Button
55
+ variant="outline"
56
+ onclick={onclickButtonRegister}
57
+ >
58
+ <HugeiconsIcon icon={User03Icon} />
59
+ {$t("label.register")}
60
+ </Button>
61
+ {/if}
62
+ {#if onclickButtonLogin}
63
+ <Button
64
+ variant="outline"
65
+ onclick={onclickButtonLogin}
66
+ >
67
+ <HugeiconsIcon icon={Login03Icon} />
68
+ {$t("label.login")}
69
+ </Button>
70
+ {/if}
71
+ </section>
72
+ </div>
73
+ </div>
74
+ <Drawer.Footer>
75
+ <div class="flex justify-center gap-5 py-5">
76
+ <LightSwitch />
77
+ <LanguageSwitcher />
78
+ </div>
79
+ <Drawer.Close class={buttonVariants({ variant: "outline" })}>
80
+ {$t("label.close")}
81
+ </Drawer.Close>
82
+ </Drawer.Footer>
83
+ </Drawer.Content>
84
+ </Drawer.Root>
85
+ </div>
@@ -1,33 +1,33 @@
1
- <script lang="ts">
2
- import * as Sidebar from "../../../ui/sidebar/index.js";
3
- import type { WithoutChildren } from "../../../../utils.js";
4
- import type { ComponentProps } from "svelte";
5
- import type { NavMenuSidebarProps } from "../data/nav-menu-sidebar";
6
- import { HugeiconsIcon } from "@hugeicons/svelte";
7
-
8
- let {
9
- items,
10
- ...restProps
11
- }: { items?: NavMenuSidebarProps[] } & WithoutChildren<
12
- ComponentProps<typeof Sidebar.Group>
13
- > = $props();
14
- </script>
15
-
16
- <Sidebar.Group {...restProps}>
17
- <Sidebar.GroupContent>
18
- <Sidebar.Menu>
19
- {#each items as item (item.title)}
20
- <Sidebar.MenuItem>
21
- <Sidebar.MenuButton>
22
- {#snippet child({ props })}
23
- <a href={item.url} {...props}>
24
- <HugeiconsIcon icon={item.icon} size={16} />
25
- <span>{item.title}</span>
26
- </a>
27
- {/snippet}
28
- </Sidebar.MenuButton>
29
- </Sidebar.MenuItem>
30
- {/each}
31
- </Sidebar.Menu>
32
- </Sidebar.GroupContent>
33
- </Sidebar.Group>
1
+ <script lang="ts">
2
+ import * as Sidebar from "../../../ui/sidebar/index.js";
3
+ import type { WithoutChildren } from "../../../../utils.js";
4
+ import type { ComponentProps } from "svelte";
5
+ import type { NavMenuSidebarProps } from "../data/nav-menu-sidebar";
6
+ import { HugeiconsIcon } from "@hugeicons/svelte";
7
+
8
+ let {
9
+ items,
10
+ ...restProps
11
+ }: { items?: NavMenuSidebarProps[] } & WithoutChildren<
12
+ ComponentProps<typeof Sidebar.Group>
13
+ > = $props();
14
+ </script>
15
+
16
+ <Sidebar.Group {...restProps}>
17
+ <Sidebar.GroupContent>
18
+ <Sidebar.Menu>
19
+ {#each items as item (item.title)}
20
+ <Sidebar.MenuItem>
21
+ <Sidebar.MenuButton>
22
+ {#snippet child({ props })}
23
+ <a href={item.url} {...props}>
24
+ <HugeiconsIcon icon={item.icon} size={16} />
25
+ <span>{item.title}</span>
26
+ </a>
27
+ {/snippet}
28
+ </Sidebar.MenuButton>
29
+ </Sidebar.MenuItem>
30
+ {/each}
31
+ </Sidebar.Menu>
32
+ </Sidebar.GroupContent>
33
+ </Sidebar.Group>
@@ -1,97 +1,97 @@
1
- <script lang="ts">
2
- /* eslint-disable @typescript-eslint/no-explicit-any */
3
- import * as Collapsible from "../../../ui/collapsible/index.js";
4
- import * as Sidebar from "../../../ui/sidebar/index.js";
5
- import ChevronRightIcon from "@lucide/svelte/icons/chevron-right";
6
- import { HugeiconsIcon } from "@hugeicons/svelte";
7
- import type {
8
- NavMenuAndSubmenuSidebarProps,
9
- NavMenuItem,
10
- NavMenuSidebarProps,
11
- } from "../data/nav-menu-sidebar";
12
-
13
- let {
14
- items,
15
- }: {
16
- items: NavMenuItem[];
17
- } = $props();
18
-
19
- // Internal key for items without a group; never collides with a real name
20
- // because it's not a string accessible to whoever defines the items.
21
- const UNGROUPED = Symbol("ungrouped");
22
-
23
- function hasSubmenus(
24
- item: NavMenuSidebarProps | NavMenuAndSubmenuSidebarProps,
25
- ): item is NavMenuAndSubmenuSidebarProps {
26
- return "submenus" in item && Array.isArray(item.submenus);
27
- }
28
-
29
- let groupedItems = $derived(
30
- Map.groupBy(items, (item) => item.group?.name ?? UNGROUPED),
31
- );
32
- </script>
33
-
34
- {#snippet menuItem(item: NavMenuItem)}
35
- {#if hasSubmenus(item)}
36
- <Collapsible.Root open={item.isActive} class="group/collapsible">
37
- {#snippet child({ props })}
38
- <Sidebar.MenuItem {...props}>
39
- <Collapsible.Trigger>
40
- {#snippet child({ props })}
41
- <Sidebar.MenuButton {...props} tooltipContent={item.title}>
42
- {#if item.icon}
43
- <HugeiconsIcon icon={item.icon} />
44
- {/if}
45
- <span>{item.title}</span>
46
- <ChevronRightIcon
47
- class="ms-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90"
48
- />
49
- </Sidebar.MenuButton>
50
- {/snippet}
51
- </Collapsible.Trigger>
52
- <Collapsible.Content>
53
- <Sidebar.MenuSub>
54
- {#each item.submenus ?? [] as subItem (subItem.title)}
55
- <Sidebar.MenuSubItem>
56
- <Sidebar.MenuSubButton>
57
- {#snippet child({ props })}
58
- <a href={subItem.url} {...props}>
59
- <span>{subItem.title}</span>
60
- </a>
61
- {/snippet}
62
- </Sidebar.MenuSubButton>
63
- </Sidebar.MenuSubItem>
64
- {/each}
65
- </Sidebar.MenuSub>
66
- </Collapsible.Content>
67
- </Sidebar.MenuItem>
68
- {/snippet}
69
- </Collapsible.Root>
70
- {:else}
71
- <Sidebar.MenuItem>
72
- <Sidebar.MenuButton>
73
- {#snippet child({ props })}
74
- <a href={item.url} {...props}>
75
- {#if item.icon}
76
- <HugeiconsIcon icon={item.icon} />
77
- {/if}
78
- <span>{item.title}</span>
79
- </a>
80
- {/snippet}
81
- </Sidebar.MenuButton>
82
- </Sidebar.MenuItem>
83
- {/if}
84
- {/snippet}
85
-
86
- {#each groupedItems as [groupLabel, groupItems] (typeof groupLabel === "string" ? groupLabel : "ungrouped")}
87
- <Sidebar.Group>
88
- {#if typeof groupLabel === "string"}
89
- <Sidebar.GroupLabel>{groupLabel}</Sidebar.GroupLabel>
90
- {/if}
91
- <Sidebar.Menu>
92
- {#each groupItems as item (item.title)}
93
- {@render menuItem(item)}
94
- {/each}
95
- </Sidebar.Menu>
96
- </Sidebar.Group>
97
- {/each}
1
+ <script lang="ts">
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3
+ import * as Collapsible from "../../../ui/collapsible/index.js";
4
+ import * as Sidebar from "../../../ui/sidebar/index.js";
5
+ import ChevronRightIcon from "@lucide/svelte/icons/chevron-right";
6
+ import { HugeiconsIcon } from "@hugeicons/svelte";
7
+ import type {
8
+ NavMenuAndSubmenuSidebarProps,
9
+ NavMenuItem,
10
+ NavMenuSidebarProps,
11
+ } from "../data/nav-menu-sidebar";
12
+
13
+ let {
14
+ items,
15
+ }: {
16
+ items: NavMenuItem[];
17
+ } = $props();
18
+
19
+ // Internal key for items without a group; never collides with a real name
20
+ // because it's not a string accessible to whoever defines the items.
21
+ const UNGROUPED = Symbol("ungrouped");
22
+
23
+ function hasSubmenus(
24
+ item: NavMenuSidebarProps | NavMenuAndSubmenuSidebarProps,
25
+ ): item is NavMenuAndSubmenuSidebarProps {
26
+ return "submenus" in item && Array.isArray(item.submenus);
27
+ }
28
+
29
+ let groupedItems = $derived(
30
+ Map.groupBy(items, (item) => item.group?.name ?? UNGROUPED),
31
+ );
32
+ </script>
33
+
34
+ {#snippet menuItem(item: NavMenuItem)}
35
+ {#if hasSubmenus(item)}
36
+ <Collapsible.Root open={item.isActive} class="group/collapsible">
37
+ {#snippet child({ props })}
38
+ <Sidebar.MenuItem {...props}>
39
+ <Collapsible.Trigger>
40
+ {#snippet child({ props })}
41
+ <Sidebar.MenuButton {...props} tooltipContent={item.title}>
42
+ {#if item.icon}
43
+ <HugeiconsIcon icon={item.icon} />
44
+ {/if}
45
+ <span>{item.title}</span>
46
+ <ChevronRightIcon
47
+ class="ms-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90"
48
+ />
49
+ </Sidebar.MenuButton>
50
+ {/snippet}
51
+ </Collapsible.Trigger>
52
+ <Collapsible.Content>
53
+ <Sidebar.MenuSub>
54
+ {#each item.submenus ?? [] as subItem (subItem.title)}
55
+ <Sidebar.MenuSubItem>
56
+ <Sidebar.MenuSubButton>
57
+ {#snippet child({ props })}
58
+ <a href={subItem.url} {...props}>
59
+ <span>{subItem.title}</span>
60
+ </a>
61
+ {/snippet}
62
+ </Sidebar.MenuSubButton>
63
+ </Sidebar.MenuSubItem>
64
+ {/each}
65
+ </Sidebar.MenuSub>
66
+ </Collapsible.Content>
67
+ </Sidebar.MenuItem>
68
+ {/snippet}
69
+ </Collapsible.Root>
70
+ {:else}
71
+ <Sidebar.MenuItem>
72
+ <Sidebar.MenuButton>
73
+ {#snippet child({ props })}
74
+ <a href={item.url} {...props}>
75
+ {#if item.icon}
76
+ <HugeiconsIcon icon={item.icon} />
77
+ {/if}
78
+ <span>{item.title}</span>
79
+ </a>
80
+ {/snippet}
81
+ </Sidebar.MenuButton>
82
+ </Sidebar.MenuItem>
83
+ {/if}
84
+ {/snippet}
85
+
86
+ {#each groupedItems as [groupLabel, groupItems] (typeof groupLabel === "string" ? groupLabel : "ungrouped")}
87
+ <Sidebar.Group>
88
+ {#if typeof groupLabel === "string"}
89
+ <Sidebar.GroupLabel>{groupLabel}</Sidebar.GroupLabel>
90
+ {/if}
91
+ <Sidebar.Menu>
92
+ {#each groupItems as item (item.title)}
93
+ {@render menuItem(item)}
94
+ {/each}
95
+ </Sidebar.Menu>
96
+ </Sidebar.Group>
97
+ {/each}