@sykoramaros/marosh-components 0.1.15 → 0.2.0

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 (35) hide show
  1. package/dist/cli/index.cjs +3 -3
  2. package/dist/index.d.ts +1006 -6
  3. package/dist/index.js +26 -25
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +2662 -3614
  6. package/dist/index.mjs.map +1 -1
  7. package/package.json +22 -7
  8. package/src/components/basicComponents/CustomButton.stories.tsx +60 -0
  9. package/src/components/basicComponents/Footer.stories.tsx +47 -0
  10. package/src/components/basicComponents/Footer.tsx +25 -14
  11. package/src/components/basicComponents/MainNav.stories.tsx +34 -0
  12. package/src/components/basicComponents/MainNav.tsx +24 -6
  13. package/src/components/basicComponents/MainSidebarLayout.stories.tsx +77 -0
  14. package/src/components/basicComponents/MainSidebarLayout.tsx +32 -27
  15. package/src/components/basicComponents/Switcher.stories.tsx +42 -0
  16. package/src/components/basicComponents/Switcher.tsx +2 -0
  17. package/src/index.ts +26 -1
  18. package/src/providers/BaseUrlProvider.tsx +24 -0
  19. package/src/providers/ThemeContextProvider.tsx +272 -0
  20. package/src/themes/bubblegum.json +134 -0
  21. package/src/themes/default.json +134 -0
  22. package/src/themes/index.ts +17 -0
  23. package/src/themes/marosh-theme.json +135 -0
  24. package/src/themes/nature.json +134 -0
  25. package/src/themes/new-theme.json +139 -0
  26. package/src/themes/retro-arcade.json +134 -0
  27. package/src/themes/tangerine.json +134 -0
  28. package/src/themes/themes/bubblegum.json +134 -0
  29. package/src/themes/themes/default.json +134 -0
  30. package/src/themes/themes/marosh-theme.json +135 -0
  31. package/src/themes/themes/nature.json +134 -0
  32. package/src/themes/themes/new-theme.json +139 -0
  33. package/src/themes/themes/retro-arcade.json +134 -0
  34. package/src/themes/themes/tangerine.json +134 -0
  35. package/src/vite-env.d.ts +1 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sykoramaros/marosh-components",
3
3
  "private": false,
4
- "version": "0.1.15",
4
+ "version": "0.2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.mjs",
@@ -29,7 +29,9 @@
29
29
  "build:cli": "bun run tsup",
30
30
  "lint": "bun run eslint .",
31
31
  "preview": "bun run vite preview",
32
- "prepublishOnly": "bun run build"
32
+ "prepublishOnly": "bun run build",
33
+ "storybook": "storybook dev -p 6006",
34
+ "build-storybook": "storybook build"
33
35
  },
34
36
  "peerDependencies": {
35
37
  "react": "^18.0.0 || ^19.0.0",
@@ -42,10 +44,6 @@
42
44
  "@radix-ui/react-slot": "^1.2.4",
43
45
  "@radix-ui/react-switch": "^1.2.6",
44
46
  "@radix-ui/react-tooltip": "^1.2.8",
45
- "@tanstack/react-router": "^1.145.6",
46
- "@tanstack/router-cli": "^1.145.6",
47
- "@tanstack/router-plugin": "^1.145.6",
48
- "ajv": "^8.17.1",
49
47
  "class-variance-authority": "^0.7.1",
50
48
  "clsx": "^2.1.1",
51
49
  "lucide-react": "^0.562.0",
@@ -54,6 +52,10 @@
54
52
  "devDependencies": {
55
53
  "@eslint/js": "^9.39.1",
56
54
  "@inquirer/prompts": "^8.2.0",
55
+ "@tanstack/react-router": "^1.145.6",
56
+ "@tanstack/router-cli": "^1.145.6",
57
+ "@tanstack/router-plugin": "^1.145.6",
58
+ "ajv": "^8.17.1",
57
59
  "@tailwindcss/vite": "^4.1.18",
58
60
  "@types/fs-extra": "^11.0.4",
59
61
  "@types/node": "^25.0.10",
@@ -76,7 +78,20 @@
76
78
  "typescript": "~5.9.3",
77
79
  "typescript-eslint": "^8.46.4",
78
80
  "vite": "^7.2.4",
79
- "vite-plugin-dts": "^4.5.4"
81
+ "vite-plugin-dts": "^4.5.4",
82
+ "storybook": "^10.4.0",
83
+ "@storybook/tanstack-react": "^10.4.0",
84
+ "@chromatic-com/storybook": "^5.2.1",
85
+ "@storybook/addon-vitest": "^10.4.0",
86
+ "@storybook/addon-a11y": "^10.4.0",
87
+ "@storybook/addon-docs": "^10.4.0",
88
+ "@storybook/addon-mcp": "^0.6.0",
89
+ "@tanstack/react-query": "^5.100.10",
90
+ "eslint-plugin-storybook": "^10.4.0",
91
+ "vitest": "^4.1.6",
92
+ "playwright": "^1.60.0",
93
+ "@vitest/browser-playwright": "^4.1.6",
94
+ "@vitest/coverage-v8": "^4.1.6"
80
95
  },
81
96
  "keywords": [
82
97
  "react",
@@ -0,0 +1,60 @@
1
+ import type { Meta, StoryObj } from "@storybook/tanstack-react"
2
+ import { CustomButton } from "./CustomButton"
3
+
4
+ const meta: Meta<typeof CustomButton> = {
5
+ title: "Components/CustomButton",
6
+ component: CustomButton,
7
+ tags: ["autodocs"],
8
+ argTypes: {
9
+ variant: {
10
+ control: "select",
11
+ options: ["default", "destructive", "outline", "secondary", "ghost", "link"],
12
+ },
13
+ size: {
14
+ control: "select",
15
+ options: ["default", "sm", "lg", "icon"],
16
+ },
17
+ disabled: { control: "boolean" },
18
+ },
19
+ }
20
+
21
+ export default meta
22
+ type Story = StoryObj<typeof CustomButton>
23
+
24
+ export const Default: Story = {
25
+ args: { children: "Button", variant: "default", size: "default" },
26
+ }
27
+
28
+ export const Destructive: Story = {
29
+ args: { children: "Delete", variant: "destructive" },
30
+ }
31
+
32
+ export const Outline: Story = {
33
+ args: { children: "Outline", variant: "outline" },
34
+ }
35
+
36
+ export const Secondary: Story = {
37
+ args: { children: "Secondary", variant: "secondary" },
38
+ }
39
+
40
+ export const Ghost: Story = {
41
+ args: { children: "Ghost", variant: "ghost" },
42
+ }
43
+
44
+ export const Disabled: Story = {
45
+ args: { children: "Disabled", variant: "default", disabled: true },
46
+ }
47
+
48
+ export const AllVariants: Story = {
49
+ render: () => (
50
+ <div className="flex flex-wrap gap-3">
51
+ {(["default", "destructive", "outline", "secondary", "ghost", "link"] as const).map(
52
+ (variant) => (
53
+ <CustomButton key={variant} variant={variant}>
54
+ {variant}
55
+ </CustomButton>
56
+ ),
57
+ )}
58
+ </div>
59
+ ),
60
+ }
@@ -0,0 +1,47 @@
1
+ import type { Meta, StoryObj } from "@storybook/tanstack-react"
2
+ import { Link } from "@tanstack/react-router"
3
+ import { Facebook, Gitlab, Linkedin } from "lucide-react"
4
+ import { Footer } from "./Footer"
5
+
6
+ const meta: Meta<typeof Footer> = {
7
+ title: "Components/Footer",
8
+ component: Footer,
9
+ tags: ["autodocs"],
10
+ }
11
+
12
+ export default meta
13
+ type Story = StoryObj<typeof Footer>
14
+
15
+ const links = [
16
+ { title: "Home", url: "/" },
17
+ { title: "About", url: "/about" },
18
+ { title: "Contact", url: "/contact" },
19
+ ]
20
+
21
+ const socialProfiles = [
22
+ { title: "Facebook", url: "https://facebook.com", icon: Facebook },
23
+ { title: "GitLab", url: "https://gitlab.com", icon: Gitlab },
24
+ { title: "LinkedIn", url: "https://linkedin.com", icon: Linkedin },
25
+ ]
26
+
27
+ export const Default: Story = {
28
+ args: {
29
+ links,
30
+ socialProfiles,
31
+ copyright: `Copyright © ${new Date().getFullYear()}`,
32
+ LinkComponent: Link,
33
+ },
34
+ }
35
+
36
+ export const NoCopyright: Story = {
37
+ args: { links, socialProfiles, LinkComponent: Link },
38
+ }
39
+
40
+ export const NoSocial: Story = {
41
+ args: {
42
+ links,
43
+ socialProfiles: [],
44
+ copyright: `Copyright © ${new Date().getFullYear()}`,
45
+ LinkComponent: Link,
46
+ },
47
+ }
@@ -1,6 +1,6 @@
1
- import { Link } from "@tanstack/react-router"
2
1
  import { LucideIcon } from "lucide-react"
3
2
  import { cn } from "@/lib/utils"
3
+ import type { LinkComponentProps } from "@/components/basicComponents/MainNav"
4
4
 
5
5
  export interface FooterLinks {
6
6
  title: string
@@ -10,7 +10,7 @@ export interface FooterLinks {
10
10
  export interface FooterSocial {
11
11
  title: string
12
12
  url: string
13
- icon?: LucideIcon | React.ComponentType
13
+ icon?: string | LucideIcon | React.ComponentType
14
14
  }
15
15
 
16
16
  export interface FooterItems extends React.ComponentPropsWithoutRef<"footer"> {
@@ -18,40 +18,51 @@ export interface FooterItems extends React.ComponentPropsWithoutRef<"footer"> {
18
18
  copyright?: string
19
19
  socialProfiles: FooterSocial[]
20
20
  className?: string
21
+ LinkComponent?: React.ComponentType<LinkComponentProps>
21
22
  }
22
23
 
24
+ const DefaultLink = ({ to, className, children, target }: LinkComponentProps) => (
25
+ <a href={to} className={className} target={target}>
26
+ {children}
27
+ </a>
28
+ )
29
+
23
30
  export const Footer = ({
24
31
  links,
25
32
  copyright,
26
33
  socialProfiles,
27
34
  className,
35
+ LinkComponent = DefaultLink,
28
36
  ...props
29
37
  }: FooterItems) => {
30
38
  return (
31
39
  <footer className={cn(className)} {...props}>
32
40
  <div className="flex flex-col items-center justify-center gap-5 bg-background py-8 border-t">
33
41
  <div className="flex justify-center gap-5 sm:gap-8 xl:gap-13">
34
- {socialProfiles.map((item) => (
35
- <Link
36
- to={item.url}
37
- className="rounded-xl"
38
- key={item.title}
39
- target="_blank"
40
- >
41
- {item.icon && <item.icon />}
42
- </Link>
43
- ))}
42
+ {socialProfiles.map((item) => {
43
+ const Icon = typeof item.icon === "string" ? null : item.icon
44
+ return (
45
+ <LinkComponent
46
+ to={item.url}
47
+ className="rounded-xl"
48
+ key={item.title}
49
+ target="_blank"
50
+ >
51
+ {Icon && <Icon />}
52
+ </LinkComponent>
53
+ )
54
+ })}
44
55
  </div>
45
56
  <div className="flex justify-center gap-5 sm:gap-8 xl:gap-13">
46
57
  {links.map((item) => {
47
58
  return (
48
- <Link
59
+ <LinkComponent
49
60
  key={item.title}
50
61
  to={item.url}
51
62
  className="no-underline! text-foreground!"
52
63
  >
53
64
  {item.title}
54
- </Link>
65
+ </LinkComponent>
55
66
  )
56
67
  })}
57
68
  </div>
@@ -0,0 +1,34 @@
1
+ import type { Meta, StoryObj } from "@storybook/tanstack-react"
2
+ import { Link } from "@tanstack/react-router"
3
+ import { Home, Info, MessageSquareMore } from "lucide-react"
4
+ import { MainNav } from "./MainNav"
5
+
6
+ const meta: Meta<typeof MainNav> = {
7
+ title: "Components/MainNav",
8
+ component: MainNav,
9
+ tags: ["autodocs"],
10
+ }
11
+
12
+ export default meta
13
+ type Story = StoryObj<typeof MainNav>
14
+
15
+ const navItems = [
16
+ { title: "Home", url: "/", icon: Home },
17
+ { title: "About", url: "/about", icon: Info },
18
+ { title: "Contact", url: "/contact", icon: MessageSquareMore },
19
+ ]
20
+
21
+ export const Default: Story = {
22
+ args: { navItems, LinkComponent: Link },
23
+ }
24
+
25
+ export const NoIcons: Story = {
26
+ args: {
27
+ navItems: navItems.map(({ title, url }) => ({ title, url })),
28
+ LinkComponent: Link,
29
+ },
30
+ }
31
+
32
+ export const Empty: Story = {
33
+ args: { navItems: [], LinkComponent: Link },
34
+ }
@@ -9,7 +9,6 @@ import { Sheet, SheetTrigger, SheetContent } from "@/components/ui/sheet"
9
9
  import { Button } from "@/components/ui/button"
10
10
  import { Menu, type LucideIcon } from "lucide-react"
11
11
  import { cn } from "@/lib/utils"
12
- import { Link } from "@tanstack/react-router"
13
12
 
14
13
  export interface NavItem {
15
14
  title: string
@@ -17,11 +16,30 @@ export interface NavItem {
17
16
  icon?: LucideIcon | React.ComponentType
18
17
  }
19
18
 
19
+ export interface LinkComponentProps {
20
+ to: string
21
+ className?: string
22
+ children?: React.ReactNode
23
+ target?: string
24
+ }
25
+
26
+ const DefaultLink = ({ to, className, children, target }: LinkComponentProps) => (
27
+ <a href={to} className={className} target={target}>
28
+ {children}
29
+ </a>
30
+ )
31
+
20
32
  export interface MainNavProps extends React.ComponentPropsWithoutRef<"header"> {
21
33
  navItems: NavItem[]
34
+ LinkComponent?: React.ComponentType<LinkComponentProps>
22
35
  }
23
36
 
24
- export const MainNav = ({ navItems, className, ...props }: MainNavProps) => {
37
+ export const MainNav = ({
38
+ navItems,
39
+ className,
40
+ LinkComponent = DefaultLink,
41
+ ...props
42
+ }: MainNavProps) => {
25
43
  return (
26
44
  <header className={cn(className)} {...props}>
27
45
  <nav className="hidden sm:flex sticky top-0 z-10 items-center px-4 h-14 bg-background">
@@ -33,13 +51,13 @@ export const MainNav = ({ navItems, className, ...props }: MainNavProps) => {
33
51
  asChild
34
52
  className={navigationMenuTriggerStyle()}
35
53
  >
36
- <Link
54
+ <LinkComponent
37
55
  to={item.url}
38
56
  className="flex items-center no-underline! text-foreground!"
39
57
  >
40
58
  {item.icon && <item.icon />}
41
59
  <span>{item.title}</span>
42
- </Link>
60
+ </LinkComponent>
43
61
  </NavigationMenuLink>
44
62
  </NavigationMenuItem>
45
63
  ))}
@@ -56,14 +74,14 @@ export const MainNav = ({ navItems, className, ...props }: MainNavProps) => {
56
74
  <SheetContent side="top" className="p-8">
57
75
  <div className="flex flex-col gap-4">
58
76
  {navItems.map((item) => (
59
- <Link
77
+ <LinkComponent
60
78
  key={item.title}
61
79
  to={item.url}
62
80
  className="flex items-center gap-2 no-underline! text-foreground!"
63
81
  >
64
82
  {item.icon && <item.icon />}
65
83
  <span className="text-base font-medium">{item.title}</span>
66
- </Link>
84
+ </LinkComponent>
67
85
  ))}
68
86
  </div>
69
87
  </SheetContent>
@@ -0,0 +1,77 @@
1
+ import type { Meta, StoryObj } from "@storybook/tanstack-react"
2
+ import { Link } from "@tanstack/react-router"
3
+ import { Home, Info, MessageSquareMore, Facebook, Gitlab, Linkedin } from "lucide-react"
4
+ import { MainSidebarLayout } from "./MainSidebarLayout"
5
+
6
+ const meta: Meta<typeof MainSidebarLayout> = {
7
+ title: "Components/MainSidebarLayout",
8
+ component: MainSidebarLayout,
9
+ tags: ["autodocs"],
10
+ parameters: {
11
+ layout: "fullscreen",
12
+ },
13
+ }
14
+
15
+ export default meta
16
+ type Story = StoryObj<typeof MainSidebarLayout>
17
+
18
+ const navItems = [
19
+ { title: "Home", url: "/", icon: Home },
20
+ { title: "About", url: "/about", icon: Info },
21
+ { title: "Contact", url: "/contact", icon: MessageSquareMore },
22
+ ]
23
+
24
+ const footerItems = {
25
+ links: [
26
+ { title: "Home", url: "/" },
27
+ { title: "About", url: "/about" },
28
+ ],
29
+ socialProfiles: [
30
+ { title: "Facebook", url: "https://facebook.com", icon: Facebook },
31
+ { title: "GitLab", url: "https://gitlab.com", icon: Gitlab },
32
+ { title: "LinkedIn", url: "https://linkedin.com", icon: Linkedin },
33
+ ],
34
+ copyright: `Copyright © ${new Date().getFullYear()}`,
35
+ }
36
+
37
+ export const WithNav: Story = {
38
+ args: {
39
+ useMainNav: true,
40
+ navItems,
41
+ LinkComponent: Link,
42
+ children: <div className="p-4">Page content</div>,
43
+ },
44
+ }
45
+
46
+ export const WithSidebar: Story = {
47
+ args: {
48
+ useSidebar: true,
49
+ appName: "My App",
50
+ navItems,
51
+ LinkComponent: Link,
52
+ children: <div className="p-4">Page content</div>,
53
+ },
54
+ }
55
+
56
+ export const WithSidebarAndFooter: Story = {
57
+ args: {
58
+ useSidebar: true,
59
+ useFooter: true,
60
+ appName: "My App",
61
+ navItems,
62
+ footerItems,
63
+ LinkComponent: Link,
64
+ children: <div className="p-4">Page content</div>,
65
+ },
66
+ }
67
+
68
+ export const NavAndFooter: Story = {
69
+ args: {
70
+ useMainNav: true,
71
+ useFooter: true,
72
+ navItems,
73
+ footerItems,
74
+ LinkComponent: Link,
75
+ children: <div className="p-4">Page content</div>,
76
+ },
77
+ }
@@ -10,8 +10,7 @@ import {
10
10
  SidebarTrigger,
11
11
  SidebarProvider,
12
12
  } from "@/components/ui/sidebar"
13
- import { Link, Outlet } from "@tanstack/react-router"
14
- import { MainNav, type NavItem } from "@/components/basicComponents/MainNav"
13
+ import { MainNav, type NavItem, type LinkComponentProps } from "@/components/basicComponents/MainNav"
15
14
  import { Footer, type FooterItems } from "@/components/basicComponents/Footer"
16
15
 
17
16
  export interface MainSidebarLayoutProps {
@@ -23,6 +22,7 @@ export interface MainSidebarLayoutProps {
23
22
  footerItems?: FooterItems
24
23
  sidebarDefaultOpen?: boolean
25
24
  children?: React.ReactNode
25
+ LinkComponent?: React.ComponentType<LinkComponentProps>
26
26
  }
27
27
 
28
28
  export const MainSidebarLayout = ({
@@ -33,25 +33,21 @@ export const MainSidebarLayout = ({
33
33
  navItems = [],
34
34
  footerItems,
35
35
  sidebarDefaultOpen = true,
36
+ children,
37
+ LinkComponent,
36
38
  }: MainSidebarLayoutProps) => {
37
- // Layout bez sidebaru
38
39
  if (!useSidebar) {
39
40
  return (
40
41
  <div className="flex-1 flex min-h-screen flex-col">
41
- {useMainNav && <MainNav navItems={navItems} />}
42
+ {useMainNav && <MainNav navItems={navItems} LinkComponent={LinkComponent} />}
42
43
  <main className="flex-1 p-5">
43
- <Outlet />
44
+ {children}
44
45
  </main>
45
- {useFooter && footerItems && (
46
- <footer>
47
- <Footer {...footerItems} />
48
- </footer>
49
- )}
46
+ {useFooter && footerItems && <Footer {...footerItems} LinkComponent={LinkComponent} />}
50
47
  </div>
51
48
  )
52
49
  }
53
50
 
54
- // Layout se sidebarem
55
51
  return (
56
52
  <SidebarProvider defaultOpen={sidebarDefaultOpen}>
57
53
  <div className="flex min-h-screen w-full">
@@ -66,16 +62,29 @@ export const MainSidebarLayout = ({
66
62
  {navItems.map((item) => (
67
63
  <SidebarMenuItem key={item.title}>
68
64
  <SidebarMenuButton asChild>
69
- <Link to={item.url}>
70
- {item.icon && (
71
- <span className="inline-flex h-5 w-5 shrink-0 items-center">
72
- <item.icon className="h-full w-full" />
65
+ {LinkComponent ? (
66
+ <LinkComponent to={item.url}>
67
+ {item.icon && (
68
+ <span className="inline-flex h-5 w-5 shrink-0 items-center">
69
+ <item.icon className="h-full w-full" />
70
+ </span>
71
+ )}
72
+ <span className="text-base font-medium">
73
+ {item.title}
73
74
  </span>
74
- )}
75
- <span className="text-base font-medium">
76
- {item.title}
77
- </span>
78
- </Link>
75
+ </LinkComponent>
76
+ ) : (
77
+ <a href={item.url}>
78
+ {item.icon && (
79
+ <span className="inline-flex h-5 w-5 shrink-0 items-center">
80
+ <item.icon className="h-full w-full" />
81
+ </span>
82
+ )}
83
+ <span className="text-base font-medium">
84
+ {item.title}
85
+ </span>
86
+ </a>
87
+ )}
79
88
  </SidebarMenuButton>
80
89
  </SidebarMenuItem>
81
90
  ))}
@@ -88,18 +97,14 @@ export const MainSidebarLayout = ({
88
97
  <div className="flex-1 flex flex-col">
89
98
  <header className="sticky top-0 z-10 flex items-center border-b bg-background px-4 h-14 gap-2">
90
99
  <SidebarTrigger />
91
- {useMainNav && <MainNav navItems={navItems} />}
100
+ {useMainNav && <MainNav navItems={navItems} LinkComponent={LinkComponent} />}
92
101
  </header>
93
102
 
94
103
  <main className="flex-1 p-6">
95
- <Outlet />
104
+ {children}
96
105
  </main>
97
106
 
98
- {useFooter && footerItems && (
99
- <footer>
100
- <Footer {...footerItems} />
101
- </footer>
102
- )}
107
+ {useFooter && footerItems && <Footer {...footerItems} LinkComponent={LinkComponent} />}
103
108
  </div>
104
109
  </div>
105
110
  </SidebarProvider>
@@ -0,0 +1,42 @@
1
+ import type { Meta, StoryObj } from "@storybook/tanstack-react"
2
+ import { Moon, Sun } from "lucide-react"
3
+ import { Switcher } from "./Switcher"
4
+
5
+ const meta: Meta<typeof Switcher> = {
6
+ title: "Components/Switcher",
7
+ component: Switcher,
8
+ tags: ["autodocs"],
9
+ argTypes: {
10
+ checked: { control: "boolean" },
11
+ disabled: { control: "boolean" },
12
+ },
13
+ }
14
+
15
+ export default meta
16
+ type Story = StoryObj<typeof Switcher>
17
+
18
+ export const Default: Story = {
19
+ args: { checked: false },
20
+ }
21
+
22
+ export const Checked: Story = {
23
+ args: { checked: true },
24
+ }
25
+
26
+ export const WithIcon: Story = {
27
+ args: {
28
+ checked: false,
29
+ icon: <Moon className="h-3 w-3" />,
30
+ },
31
+ }
32
+
33
+ export const WithIconChecked: Story = {
34
+ args: {
35
+ checked: true,
36
+ icon: <Sun className="h-3 w-3" />,
37
+ },
38
+ }
39
+
40
+ export const Disabled: Story = {
41
+ args: { checked: false, disabled: true },
42
+ }
@@ -25,3 +25,5 @@ export const Switcher = React.forwardRef<
25
25
  </SwitchPrimitives.Thumb>
26
26
  </SwitchPrimitives.Root>
27
27
  ))
28
+
29
+ Switcher.displayName = "Switcher"
package/src/index.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export { cn } from "@/lib/utils.ts"
2
- export { Link } from "@tanstack/react-router"
2
+
3
+ // COMPONENTS
4
+
3
5
  export {
4
6
  CustomButton,
5
7
  type CustomButtonProps,
@@ -8,6 +10,7 @@ export {
8
10
  MainNav,
9
11
  type NavItem,
10
12
  type MainNavProps,
13
+ type LinkComponentProps,
11
14
  } from "@/components/basicComponents/MainNav"
12
15
  export {
13
16
  Footer,
@@ -20,3 +23,25 @@ export {
20
23
  type MainSidebarLayoutProps,
21
24
  } from "@/components/basicComponents/MainSidebarLayout"
22
25
  export { Switcher } from "@/components/basicComponents/Switcher"
26
+
27
+ // PROVIDERS
28
+ export {
29
+ BaseUrlProvider,
30
+ useBaseUrl,
31
+ type BaseUrlProviderProps,
32
+ } from "@/providers/BaseUrlProvider"
33
+
34
+ export {
35
+ ThemeContextProvider,
36
+ useThemeContext,
37
+ type ThemeContextProviderProps,
38
+ type ThemeConfig,
39
+ type ThemeRegistry,
40
+ type ThemeMode,
41
+ } from "@/providers/ThemeContextProvider"
42
+
43
+ // HOOKS
44
+ // ...
45
+
46
+ // THEMES
47
+ export { themeData } from "@/themes/index"
@@ -0,0 +1,24 @@
1
+ import { createContext, useContext, ReactNode } from "react"
2
+
3
+ export const BaseUrlContext = createContext<string | undefined>(undefined)
4
+
5
+ export interface BaseUrlProviderProps {
6
+ children: ReactNode
7
+ value: string
8
+ }
9
+
10
+ export const BaseUrlProvider = ({ children, value }: BaseUrlProviderProps) => {
11
+ return (
12
+ <BaseUrlContext.Provider value={value}>{children}</BaseUrlContext.Provider>
13
+ )
14
+ }
15
+
16
+ export const useBaseUrl = (): string => {
17
+ const context = useContext(BaseUrlContext)
18
+
19
+ if (context === undefined) {
20
+ throw new Error("useBaseUrl must be used within BaseUrlProvider")
21
+ }
22
+
23
+ return context
24
+ }