@sykoramaros/marosh-components 0.2.0 → 0.2.3
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/cli/index.cjs +510 -534
- package/dist/index.d.ts +17 -1
- package/dist/index.js +13 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2900 -1944
- package/dist/index.mjs.map +1 -1
- package/package.json +26 -25
- package/src/components/basicComponents/LanguageSwitcher.stories.tsx +52 -0
- package/src/components/basicComponents/LanguageSwitcher.tsx +84 -0
- package/src/components/ui/dropdown-menu.tsx +171 -0
- package/src/components/ui/sidebar.tsx +1 -0
- package/src/hooks/use-mobile.ts +5 -6
- package/src/index.ts +5 -0
- package/src/providers/ThemeContextProvider.tsx +1 -1
- package/src/App.css +0 -42
- package/src/App.tsx +0 -44
- package/src/main.tsx +0 -23
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sykoramaros/marosh-components",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"module": "./dist/index.mjs",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"README.md"
|
|
24
24
|
],
|
|
25
25
|
"scripts": {
|
|
26
|
-
"dev": "
|
|
26
|
+
"dev": "storybook dev -p 6006",
|
|
27
27
|
"build": "bun run build:lib && bun run build:cli",
|
|
28
28
|
"build:lib": "bun run vite build",
|
|
29
29
|
"build:cli": "bun run tsup",
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
42
|
+
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
42
43
|
"@radix-ui/react-navigation-menu": "^1.2.14",
|
|
43
44
|
"@radix-ui/react-separator": "^1.1.8",
|
|
44
45
|
"@radix-ui/react-slot": "^1.2.4",
|
|
@@ -47,37 +48,37 @@
|
|
|
47
48
|
"class-variance-authority": "^0.7.1",
|
|
48
49
|
"clsx": "^2.1.1",
|
|
49
50
|
"lucide-react": "^0.562.0",
|
|
50
|
-
"tailwind-merge": "^3.
|
|
51
|
+
"tailwind-merge": "^3.6.0"
|
|
51
52
|
},
|
|
52
53
|
"devDependencies": {
|
|
53
|
-
"@eslint/js": "^9.39.
|
|
54
|
-
"@inquirer/prompts": "^8.
|
|
55
|
-
"@tanstack/react-router": "^1.
|
|
56
|
-
"@tanstack/router-cli": "^1.
|
|
57
|
-
"@tanstack/router-plugin": "^1.
|
|
58
|
-
"ajv": "^8.
|
|
59
|
-
"@tailwindcss/vite": "^4.
|
|
54
|
+
"@eslint/js": "^9.39.4",
|
|
55
|
+
"@inquirer/prompts": "^8.4.3",
|
|
56
|
+
"@tanstack/react-router": "^1.169.2",
|
|
57
|
+
"@tanstack/router-cli": "^1.166.43",
|
|
58
|
+
"@tanstack/router-plugin": "^1.167.35",
|
|
59
|
+
"ajv": "^8.20.0",
|
|
60
|
+
"@tailwindcss/vite": "^4.3.0",
|
|
60
61
|
"@types/fs-extra": "^11.0.4",
|
|
61
|
-
"@types/node": "^25.0
|
|
62
|
-
"@types/react": "^19.2.
|
|
62
|
+
"@types/node": "^25.8.0",
|
|
63
|
+
"@types/react": "^19.2.14",
|
|
63
64
|
"@types/react-dom": "^19.2.3",
|
|
64
|
-
"@vitejs/plugin-react": "^5.
|
|
65
|
-
"autoprefixer": "^10.
|
|
66
|
-
"commander": "^14.0.
|
|
67
|
-
"eslint": "^9.39.
|
|
68
|
-
"eslint-plugin-react-hooks": "^7.
|
|
69
|
-
"eslint-plugin-react-refresh": "^0.4.
|
|
70
|
-
"fs-extra": "^11.3.
|
|
65
|
+
"@vitejs/plugin-react": "^5.2.0",
|
|
66
|
+
"autoprefixer": "^10.5.0",
|
|
67
|
+
"commander": "^14.0.3",
|
|
68
|
+
"eslint": "^9.39.4",
|
|
69
|
+
"eslint-plugin-react-hooks": "^7.1.1",
|
|
70
|
+
"eslint-plugin-react-refresh": "^0.4.26",
|
|
71
|
+
"fs-extra": "^11.3.5",
|
|
71
72
|
"globals": "^16.5.0",
|
|
72
|
-
"postcss": "^8.5.
|
|
73
|
-
"react": "^19.2.
|
|
74
|
-
"react-dom": "^19.2.
|
|
75
|
-
"tailwindcss": "^4.
|
|
73
|
+
"postcss": "^8.5.14",
|
|
74
|
+
"react": "^19.2.6",
|
|
75
|
+
"react-dom": "^19.2.6",
|
|
76
|
+
"tailwindcss": "^4.3.0",
|
|
76
77
|
"tsup": "^8.5.1",
|
|
77
78
|
"tw-animate-css": "^1.4.0",
|
|
78
79
|
"typescript": "~5.9.3",
|
|
79
|
-
"typescript-eslint": "^8.
|
|
80
|
-
"vite": "^7.
|
|
80
|
+
"typescript-eslint": "^8.59.3",
|
|
81
|
+
"vite": "^7.3.3",
|
|
81
82
|
"vite-plugin-dts": "^4.5.4",
|
|
82
83
|
"storybook": "^10.4.0",
|
|
83
84
|
"@storybook/tanstack-react": "^10.4.0",
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/tanstack-react"
|
|
2
|
+
import { useState } from "react"
|
|
3
|
+
import { LanguageSwitcher } from "./LanguageSwitcher"
|
|
4
|
+
|
|
5
|
+
const LANGUAGES = [
|
|
6
|
+
{ code: "en", label: "English", flag: "🇺🇸" },
|
|
7
|
+
{ code: "fr", label: "Français", flag: "🇫🇷" },
|
|
8
|
+
{ code: "es", label: "Español", flag: "🇪🇸" },
|
|
9
|
+
{ code: "cs", label: "Čeština", flag: "🇨🇿" },
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
const meta: Meta<typeof LanguageSwitcher> = {
|
|
13
|
+
title: "Components/LanguageSwitcher",
|
|
14
|
+
component: LanguageSwitcher,
|
|
15
|
+
tags: ["autodocs"],
|
|
16
|
+
parameters: {
|
|
17
|
+
layout: "centered",
|
|
18
|
+
},
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default meta
|
|
22
|
+
type Story = StoryObj<typeof LanguageSwitcher>
|
|
23
|
+
|
|
24
|
+
export const Default: Story = {
|
|
25
|
+
render: () => {
|
|
26
|
+
const [lang, setLang] = useState("en")
|
|
27
|
+
return <LanguageSwitcher languages={LANGUAGES} value={lang} onChange={setLang} />
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const Bubble: Story = {
|
|
32
|
+
render: () => {
|
|
33
|
+
const [lang, setLang] = useState("en")
|
|
34
|
+
return <LanguageSwitcher languages={LANGUAGES} value={lang} onChange={setLang} variant="bubble" />
|
|
35
|
+
},
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const TwoLanguages: Story = {
|
|
39
|
+
render: () => {
|
|
40
|
+
const [lang, setLang] = useState("en")
|
|
41
|
+
return (
|
|
42
|
+
<LanguageSwitcher
|
|
43
|
+
languages={[
|
|
44
|
+
{ code: "en", label: "English", flag: "🇺🇸" },
|
|
45
|
+
{ code: "cs", label: "Čeština", flag: "🇨🇿" },
|
|
46
|
+
]}
|
|
47
|
+
value={lang}
|
|
48
|
+
onChange={setLang}
|
|
49
|
+
/>
|
|
50
|
+
)
|
|
51
|
+
},
|
|
52
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { ChevronDown } from "lucide-react"
|
|
2
|
+
import { cn } from "@/lib/utils"
|
|
3
|
+
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
|
|
4
|
+
|
|
5
|
+
export interface Language {
|
|
6
|
+
code: string
|
|
7
|
+
label: string
|
|
8
|
+
flag: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface LanguageSwitcherProps {
|
|
12
|
+
languages: Language[]
|
|
13
|
+
value: string
|
|
14
|
+
onChange: (code: string) => void
|
|
15
|
+
variant?: "default" | "bubble"
|
|
16
|
+
className?: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function LanguageSwitcher({
|
|
20
|
+
languages,
|
|
21
|
+
value,
|
|
22
|
+
onChange,
|
|
23
|
+
variant = "default",
|
|
24
|
+
className,
|
|
25
|
+
}: LanguageSwitcherProps) {
|
|
26
|
+
const current = languages.find((l) => l.code === value) ?? languages[0]
|
|
27
|
+
const isBubble = variant === "bubble"
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<DropdownMenuPrimitive.Root>
|
|
31
|
+
<DropdownMenuPrimitive.Trigger
|
|
32
|
+
className={cn(
|
|
33
|
+
"flex items-center transition-colors focus:outline-none",
|
|
34
|
+
isBubble
|
|
35
|
+
? "gap-1 rounded-lg border border-border bg-background px-2 py-0.5 text-sm font-medium shadow-sm hover:bg-accent"
|
|
36
|
+
: "gap-1.5 rounded-md px-2.5 py-1.5 text-sm font-medium hover:bg-accent",
|
|
37
|
+
className
|
|
38
|
+
)}
|
|
39
|
+
>
|
|
40
|
+
<span className={cn("leading-none", isBubble ? "text-lg" : "text-base")}>{current.flag}</span>
|
|
41
|
+
{!isBubble && <span>{current.code.toUpperCase()}</span>}
|
|
42
|
+
<ChevronDown className={cn("opacity-60", isBubble ? "h-3 w-3 opacity-50" : "h-3.5 w-3.5")} />
|
|
43
|
+
</DropdownMenuPrimitive.Trigger>
|
|
44
|
+
|
|
45
|
+
<DropdownMenuPrimitive.Portal>
|
|
46
|
+
<DropdownMenuPrimitive.Content
|
|
47
|
+
align="end"
|
|
48
|
+
sideOffset={isBubble ? 10 : 4}
|
|
49
|
+
className={cn(
|
|
50
|
+
"relative z-50 overflow-visible p-1.5",
|
|
51
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
52
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
53
|
+
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
54
|
+
"data-[side=bottom]:slide-in-from-top-2",
|
|
55
|
+
isBubble
|
|
56
|
+
? "group min-w-37.5 rounded-2xl border border-border bg-white shadow-xl"
|
|
57
|
+
: "min-w-35 rounded-md border bg-popover text-popover-foreground shadow-md"
|
|
58
|
+
)}
|
|
59
|
+
>
|
|
60
|
+
{isBubble && (
|
|
61
|
+
<span className="absolute right-4 h-3.5 w-3.5 rotate-45 border-border bg-white group-data-[side=bottom]:-top-1.75 group-data-[side=bottom]:rounded-tl-sm group-data-[side=bottom]:border-l group-data-[side=bottom]:border-t group-data-[side=top]:-bottom-1.75 group-data-[side=top]:rounded-br-sm group-data-[side=top]:border-r group-data-[side=top]:border-b" />
|
|
62
|
+
)}
|
|
63
|
+
|
|
64
|
+
{languages.map((lang) => (
|
|
65
|
+
<DropdownMenuPrimitive.Item
|
|
66
|
+
key={lang.code}
|
|
67
|
+
onSelect={() => onChange(lang.code)}
|
|
68
|
+
className={cn(
|
|
69
|
+
"flex cursor-pointer select-none items-center outline-none transition-colors focus:bg-accent",
|
|
70
|
+
isBubble
|
|
71
|
+
? "gap-3 rounded-xl px-3 py-2 text-sm"
|
|
72
|
+
: "gap-2.5 rounded-sm px-2 py-1.5 text-sm",
|
|
73
|
+
lang.code === value && (isBubble ? "bg-accent font-medium" : "bg-accent")
|
|
74
|
+
)}
|
|
75
|
+
>
|
|
76
|
+
<span className={cn("leading-none", isBubble ? "text-xl" : "text-base")}>{lang.flag}</span>
|
|
77
|
+
<span>{lang.label}</span>
|
|
78
|
+
</DropdownMenuPrimitive.Item>
|
|
79
|
+
))}
|
|
80
|
+
</DropdownMenuPrimitive.Content>
|
|
81
|
+
</DropdownMenuPrimitive.Portal>
|
|
82
|
+
</DropdownMenuPrimitive.Root>
|
|
83
|
+
)
|
|
84
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
|
|
3
|
+
import { Check, ChevronRight, Circle } from "lucide-react"
|
|
4
|
+
import { cn } from "@/lib/utils"
|
|
5
|
+
|
|
6
|
+
const DropdownMenu = DropdownMenuPrimitive.Root
|
|
7
|
+
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
|
|
8
|
+
const DropdownMenuGroup = DropdownMenuPrimitive.Group
|
|
9
|
+
const DropdownMenuPortal = DropdownMenuPrimitive.Portal
|
|
10
|
+
const DropdownMenuSub = DropdownMenuPrimitive.Sub
|
|
11
|
+
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
|
|
12
|
+
|
|
13
|
+
const DropdownMenuSubTrigger = React.forwardRef<
|
|
14
|
+
React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
|
|
15
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & { inset?: boolean }
|
|
16
|
+
>(({ className, inset, children, ...props }, ref) => (
|
|
17
|
+
<DropdownMenuPrimitive.SubTrigger
|
|
18
|
+
ref={ref}
|
|
19
|
+
className={cn(
|
|
20
|
+
"flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
21
|
+
inset && "pl-8",
|
|
22
|
+
className
|
|
23
|
+
)}
|
|
24
|
+
{...props}
|
|
25
|
+
>
|
|
26
|
+
{children}
|
|
27
|
+
<ChevronRight className="ml-auto" />
|
|
28
|
+
</DropdownMenuPrimitive.SubTrigger>
|
|
29
|
+
))
|
|
30
|
+
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName
|
|
31
|
+
|
|
32
|
+
const DropdownMenuSubContent = React.forwardRef<
|
|
33
|
+
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
|
|
34
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
|
|
35
|
+
>(({ className, ...props }, ref) => (
|
|
36
|
+
<DropdownMenuPrimitive.SubContent
|
|
37
|
+
ref={ref}
|
|
38
|
+
className={cn(
|
|
39
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
40
|
+
className
|
|
41
|
+
)}
|
|
42
|
+
{...props}
|
|
43
|
+
/>
|
|
44
|
+
))
|
|
45
|
+
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName
|
|
46
|
+
|
|
47
|
+
const DropdownMenuContent = React.forwardRef<
|
|
48
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
|
|
49
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
|
|
50
|
+
>(({ className, sideOffset = 4, ...props }, ref) => (
|
|
51
|
+
<DropdownMenuPrimitive.Portal>
|
|
52
|
+
<DropdownMenuPrimitive.Content
|
|
53
|
+
ref={ref}
|
|
54
|
+
sideOffset={sideOffset}
|
|
55
|
+
className={cn(
|
|
56
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
57
|
+
className
|
|
58
|
+
)}
|
|
59
|
+
{...props}
|
|
60
|
+
/>
|
|
61
|
+
</DropdownMenuPrimitive.Portal>
|
|
62
|
+
))
|
|
63
|
+
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
|
|
64
|
+
|
|
65
|
+
const DropdownMenuItem = React.forwardRef<
|
|
66
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
|
|
67
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & { inset?: boolean }
|
|
68
|
+
>(({ className, inset, ...props }, ref) => (
|
|
69
|
+
<DropdownMenuPrimitive.Item
|
|
70
|
+
ref={ref}
|
|
71
|
+
className={cn(
|
|
72
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
73
|
+
inset && "pl-8",
|
|
74
|
+
className
|
|
75
|
+
)}
|
|
76
|
+
{...props}
|
|
77
|
+
/>
|
|
78
|
+
))
|
|
79
|
+
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
|
|
80
|
+
|
|
81
|
+
const DropdownMenuCheckboxItem = React.forwardRef<
|
|
82
|
+
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
|
|
83
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
|
|
84
|
+
>(({ className, children, checked, ...props }, ref) => (
|
|
85
|
+
<DropdownMenuPrimitive.CheckboxItem
|
|
86
|
+
ref={ref}
|
|
87
|
+
className={cn(
|
|
88
|
+
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
89
|
+
className
|
|
90
|
+
)}
|
|
91
|
+
checked={checked}
|
|
92
|
+
{...props}
|
|
93
|
+
>
|
|
94
|
+
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
95
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
96
|
+
<Check className="h-4 w-4" />
|
|
97
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
98
|
+
</span>
|
|
99
|
+
{children}
|
|
100
|
+
</DropdownMenuPrimitive.CheckboxItem>
|
|
101
|
+
))
|
|
102
|
+
DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName
|
|
103
|
+
|
|
104
|
+
const DropdownMenuRadioItem = React.forwardRef<
|
|
105
|
+
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
|
|
106
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
|
|
107
|
+
>(({ className, children, ...props }, ref) => (
|
|
108
|
+
<DropdownMenuPrimitive.RadioItem
|
|
109
|
+
ref={ref}
|
|
110
|
+
className={cn(
|
|
111
|
+
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
112
|
+
className
|
|
113
|
+
)}
|
|
114
|
+
{...props}
|
|
115
|
+
>
|
|
116
|
+
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
117
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
118
|
+
<Circle className="h-2 w-2 fill-current" />
|
|
119
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
120
|
+
</span>
|
|
121
|
+
{children}
|
|
122
|
+
</DropdownMenuPrimitive.RadioItem>
|
|
123
|
+
))
|
|
124
|
+
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName
|
|
125
|
+
|
|
126
|
+
const DropdownMenuLabel = React.forwardRef<
|
|
127
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Label>,
|
|
128
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & { inset?: boolean }
|
|
129
|
+
>(({ className, inset, ...props }, ref) => (
|
|
130
|
+
<DropdownMenuPrimitive.Label
|
|
131
|
+
ref={ref}
|
|
132
|
+
className={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
|
|
133
|
+
{...props}
|
|
134
|
+
/>
|
|
135
|
+
))
|
|
136
|
+
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
|
|
137
|
+
|
|
138
|
+
const DropdownMenuSeparator = React.forwardRef<
|
|
139
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
|
|
140
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
|
|
141
|
+
>(({ className, ...props }, ref) => (
|
|
142
|
+
<DropdownMenuPrimitive.Separator
|
|
143
|
+
ref={ref}
|
|
144
|
+
className={cn("-mx-1 my-1 h-px bg-muted", className)}
|
|
145
|
+
{...props}
|
|
146
|
+
/>
|
|
147
|
+
))
|
|
148
|
+
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
|
|
149
|
+
|
|
150
|
+
const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => (
|
|
151
|
+
<span className={cn("ml-auto text-xs tracking-widest opacity-60", className)} {...props} />
|
|
152
|
+
)
|
|
153
|
+
DropdownMenuShortcut.displayName = "DropdownMenuShortcut"
|
|
154
|
+
|
|
155
|
+
export {
|
|
156
|
+
DropdownMenu,
|
|
157
|
+
DropdownMenuTrigger,
|
|
158
|
+
DropdownMenuContent,
|
|
159
|
+
DropdownMenuItem,
|
|
160
|
+
DropdownMenuCheckboxItem,
|
|
161
|
+
DropdownMenuRadioItem,
|
|
162
|
+
DropdownMenuLabel,
|
|
163
|
+
DropdownMenuSeparator,
|
|
164
|
+
DropdownMenuShortcut,
|
|
165
|
+
DropdownMenuGroup,
|
|
166
|
+
DropdownMenuPortal,
|
|
167
|
+
DropdownMenuSub,
|
|
168
|
+
DropdownMenuSubContent,
|
|
169
|
+
DropdownMenuSubTrigger,
|
|
170
|
+
DropdownMenuRadioGroup,
|
|
171
|
+
}
|
package/src/hooks/use-mobile.ts
CHANGED
|
@@ -3,17 +3,16 @@ import * as React from "react"
|
|
|
3
3
|
const MOBILE_BREAKPOINT = 768
|
|
4
4
|
|
|
5
5
|
export function useIsMobile() {
|
|
6
|
-
const [isMobile, setIsMobile] = React.useState
|
|
6
|
+
const [isMobile, setIsMobile] = React.useState(
|
|
7
|
+
() => window.innerWidth < MOBILE_BREAKPOINT,
|
|
8
|
+
)
|
|
7
9
|
|
|
8
10
|
React.useEffect(() => {
|
|
9
11
|
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
|
|
10
|
-
const onChange = () =>
|
|
11
|
-
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
|
|
12
|
-
}
|
|
12
|
+
const onChange = () => setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
|
|
13
13
|
mql.addEventListener("change", onChange)
|
|
14
|
-
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
|
|
15
14
|
return () => mql.removeEventListener("change", onChange)
|
|
16
15
|
}, [])
|
|
17
16
|
|
|
18
|
-
return
|
|
17
|
+
return isMobile
|
|
19
18
|
}
|
package/src/index.ts
CHANGED
|
@@ -23,6 +23,11 @@ export {
|
|
|
23
23
|
type MainSidebarLayoutProps,
|
|
24
24
|
} from "@/components/basicComponents/MainSidebarLayout"
|
|
25
25
|
export { Switcher } from "@/components/basicComponents/Switcher"
|
|
26
|
+
export {
|
|
27
|
+
LanguageSwitcher,
|
|
28
|
+
type Language,
|
|
29
|
+
type LanguageSwitcherProps,
|
|
30
|
+
} from "@/components/basicComponents/LanguageSwitcher"
|
|
26
31
|
|
|
27
32
|
// PROVIDERS
|
|
28
33
|
export {
|
package/src/App.css
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/* #root {
|
|
2
|
-
max-width: 1280px;
|
|
3
|
-
margin: 0 auto;
|
|
4
|
-
padding: 2rem;
|
|
5
|
-
text-align: center;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
.logo {
|
|
9
|
-
height: 6em;
|
|
10
|
-
padding: 1.5em;
|
|
11
|
-
will-change: filter;
|
|
12
|
-
transition: filter 300ms;
|
|
13
|
-
}
|
|
14
|
-
.logo:hover {
|
|
15
|
-
filter: drop-shadow(0 0 2em #646cffaa);
|
|
16
|
-
}
|
|
17
|
-
.logo.react:hover {
|
|
18
|
-
filter: drop-shadow(0 0 2em #61dafbaa);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
@keyframes logo-spin {
|
|
22
|
-
from {
|
|
23
|
-
transform: rotate(0deg);
|
|
24
|
-
}
|
|
25
|
-
to {
|
|
26
|
-
transform: rotate(360deg);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
@media (prefers-reduced-motion: no-preference) {
|
|
31
|
-
a:nth-of-type(2) .logo {
|
|
32
|
-
animation: logo-spin infinite 20s linear;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
.card {
|
|
37
|
-
padding: 2em;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.read-the-docs {
|
|
41
|
-
color: #888;
|
|
42
|
-
} */
|
package/src/App.tsx
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { Button } from "@/components/ui/button"
|
|
2
|
-
import { CustomButton } from "@/components/basicComponents/CustomButton"
|
|
3
|
-
import { MainNav } from "@/components/basicComponents/MainNav"
|
|
4
|
-
import { Github, Menu, Twitter } from "lucide-react"
|
|
5
|
-
import { Footer } from "@/components/basicComponents/Footer"
|
|
6
|
-
|
|
7
|
-
export const App = () => {
|
|
8
|
-
return (
|
|
9
|
-
<>
|
|
10
|
-
<MainNav
|
|
11
|
-
navItems={[
|
|
12
|
-
{ title: "Home", url: "/", icon: Menu },
|
|
13
|
-
{ title: "About", url: "/about", icon: Menu },
|
|
14
|
-
{ title: "Contact", url: "/contact", icon: Menu },
|
|
15
|
-
]}
|
|
16
|
-
/>
|
|
17
|
-
<div className="p-13 flex gap-5">
|
|
18
|
-
<Button>Shadcn UI Test</Button>
|
|
19
|
-
<CustomButton>Custom Button</CustomButton>
|
|
20
|
-
</div>
|
|
21
|
-
<Footer
|
|
22
|
-
className="fixed bottom-0 w-full"
|
|
23
|
-
links={[
|
|
24
|
-
{ title: "Home", url: "/" },
|
|
25
|
-
{ title: "About", url: "/about" },
|
|
26
|
-
{ title: "Contact", url: "/contact" },
|
|
27
|
-
]}
|
|
28
|
-
socialProfiles={[
|
|
29
|
-
{
|
|
30
|
-
title: "Twitter",
|
|
31
|
-
url: "https://twitter.com/shadcn",
|
|
32
|
-
icon: Twitter,
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
title: "GitHub",
|
|
36
|
-
url: "https://github.com/shadcn",
|
|
37
|
-
icon: Github,
|
|
38
|
-
},
|
|
39
|
-
]}
|
|
40
|
-
copyright="© 2026 Marosh Sykora"
|
|
41
|
-
/>
|
|
42
|
-
</>
|
|
43
|
-
)
|
|
44
|
-
}
|
package/src/main.tsx
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { StrictMode } from "react"
|
|
2
|
-
import { createRoot } from "react-dom/client"
|
|
3
|
-
import {
|
|
4
|
-
createRouter,
|
|
5
|
-
createRootRoute,
|
|
6
|
-
RouterProvider,
|
|
7
|
-
} from "@tanstack/react-router"
|
|
8
|
-
import "./index.css"
|
|
9
|
-
import { App } from "./App.tsx"
|
|
10
|
-
|
|
11
|
-
const rootRoute = createRootRoute({
|
|
12
|
-
component: App,
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
const router = createRouter({
|
|
16
|
-
routeTree: rootRoute,
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
createRoot(document.getElementById("root")!).render(
|
|
20
|
-
<StrictMode>
|
|
21
|
-
<RouterProvider router={router} />
|
|
22
|
-
</StrictMode>,
|
|
23
|
-
)
|