modula-ui 1.0.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 (66) hide show
  1. package/README.md +36 -0
  2. package/bin/run.js +86 -0
  3. package/package.json +71 -0
  4. package/public/avatars/avatar1.png +0 -0
  5. package/public/avatars/avatar2.png +0 -0
  6. package/public/avatars/avatar3.png +0 -0
  7. package/public/avatars/avatar4.png +0 -0
  8. package/public/avatars/sources.md +34 -0
  9. package/public/file.svg +1 -0
  10. package/public/globe.svg +1 -0
  11. package/public/next.svg +1 -0
  12. package/public/vercel.svg +1 -0
  13. package/public/window.svg +1 -0
  14. package/registry.json +12 -0
  15. package/src/app/favicon.ico +0 -0
  16. package/src/app/globals.css +126 -0
  17. package/src/app/layout.js +29 -0
  18. package/src/app/page.js +50 -0
  19. package/src/app/patterns/page.js +50 -0
  20. package/src/components/CodeCard.jsx +16 -0
  21. package/src/components/CopyButton.jsx +31 -0
  22. package/src/components/Header.jsx +24 -0
  23. package/src/components/Logo.jsx +64 -0
  24. package/src/components/MobileOverlay.jsx +10 -0
  25. package/src/components/PreviewCard.jsx +98 -0
  26. package/src/components/Sidebar.jsx +47 -0
  27. package/src/components/ui/avatar.jsx +47 -0
  28. package/src/components/ui/badge.jsx +44 -0
  29. package/src/components/ui/button.jsx +56 -0
  30. package/src/components/ui/calendar.jsx +178 -0
  31. package/src/components/ui/card.jsx +101 -0
  32. package/src/components/ui/chart.jsx +314 -0
  33. package/src/components/ui/checkbox.jsx +30 -0
  34. package/src/components/ui/dropdown-menu.jsx +223 -0
  35. package/src/components/ui/input.jsx +24 -0
  36. package/src/components/ui/navigation-menu.jsx +152 -0
  37. package/src/components/ui/popover.jsx +47 -0
  38. package/src/components/ui/progress.jsx +29 -0
  39. package/src/components/ui/scroll-area.jsx +51 -0
  40. package/src/components/ui/select.jsx +168 -0
  41. package/src/components/ui/separator.jsx +27 -0
  42. package/src/components/ui/sheet.jsx +140 -0
  43. package/src/components/ui/sidebar.jsx +682 -0
  44. package/src/components/ui/skeleton.jsx +15 -0
  45. package/src/components/ui/slider.jsx +56 -0
  46. package/src/components/ui/tooltip.jsx +55 -0
  47. package/src/data/componentData.js +12 -0
  48. package/src/hooks/use-mobile.js +19 -0
  49. package/src/lib/utils.js +6 -0
  50. package/src/library/components/Alert.jsx +27 -0
  51. package/src/library/components/Badge.jsx +19 -0
  52. package/src/library/components/Button.jsx +31 -0
  53. package/src/library/components/Card.jsx +25 -0
  54. package/src/library/components/Input.jsx +35 -0
  55. package/src/library/components/Modal.jsx +26 -0
  56. package/src/library/components/Textarea.jsx +15 -0
  57. package/src/library/components/Toggle.jsx +16 -0
  58. package/src/library/pages/FitnessPage/FitnessPage.jsx +519 -0
  59. package/src/library/pages/FitnessPage/index.jsx +12 -0
  60. package/src/library/pages/GroupChat/GroupChat.jsx +275 -0
  61. package/src/library/pages/GroupChat/data.js +203 -0
  62. package/src/library/pages/GroupChat/index.jsx +12 -0
  63. package/src/library/pages/ReservationsOverview/ReservationsOverviewPage.jsx +225 -0
  64. package/src/library/pages/ReservationsOverview/index.jsx +12 -0
  65. package/src/library/pages/VideoConference/VideoConferencePage.jsx +334 -0
  66. package/src/library/pages/VideoConference/index.jsx +12 -0
@@ -0,0 +1,56 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as SliderPrimitive from "@radix-ui/react-slider"
5
+
6
+ import { cn } from "@/lib/utils"
7
+
8
+ function Slider({
9
+ className,
10
+ defaultValue,
11
+ value,
12
+ min = 0,
13
+ max = 100,
14
+ ...props
15
+ }) {
16
+ const _values = React.useMemo(() =>
17
+ Array.isArray(value)
18
+ ? value
19
+ : Array.isArray(defaultValue)
20
+ ? defaultValue
21
+ : [min, max], [value, defaultValue, min, max])
22
+
23
+ return (
24
+ <SliderPrimitive.Root
25
+ data-slot="slider"
26
+ defaultValue={defaultValue}
27
+ value={value}
28
+ min={min}
29
+ max={max}
30
+ className={cn(
31
+ "relative flex w-full touch-none items-center select-none data-[disabled]:opacity-50 data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col",
32
+ className
33
+ )}
34
+ {...props}>
35
+ <SliderPrimitive.Track
36
+ data-slot="slider-track"
37
+ className={cn(
38
+ "bg-muted relative grow overflow-hidden rounded-full data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5"
39
+ )}>
40
+ <SliderPrimitive.Range
41
+ data-slot="slider-range"
42
+ className={cn(
43
+ "bg-primary absolute data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full"
44
+ )} />
45
+ </SliderPrimitive.Track>
46
+ {Array.from({ length: _values.length }, (_, index) => (
47
+ <SliderPrimitive.Thumb
48
+ data-slot="slider-thumb"
49
+ key={index}
50
+ className="border-primary ring-ring/50 block size-4 shrink-0 rounded-full border bg-white shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50" />
51
+ ))}
52
+ </SliderPrimitive.Root>
53
+ );
54
+ }
55
+
56
+ export { Slider }
@@ -0,0 +1,55 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as TooltipPrimitive from "@radix-ui/react-tooltip"
5
+
6
+ import { cn } from "@/lib/utils"
7
+
8
+ function TooltipProvider({
9
+ delayDuration = 0,
10
+ ...props
11
+ }) {
12
+ return (<TooltipPrimitive.Provider data-slot="tooltip-provider" delayDuration={delayDuration} {...props} />);
13
+ }
14
+
15
+ function Tooltip({
16
+ ...props
17
+ }) {
18
+ return (
19
+ <TooltipProvider>
20
+ <TooltipPrimitive.Root data-slot="tooltip" {...props} />
21
+ </TooltipProvider>
22
+ );
23
+ }
24
+
25
+ function TooltipTrigger({
26
+ ...props
27
+ }) {
28
+ return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;
29
+ }
30
+
31
+ function TooltipContent({
32
+ className,
33
+ sideOffset = 0,
34
+ children,
35
+ ...props
36
+ }) {
37
+ return (
38
+ <TooltipPrimitive.Portal>
39
+ <TooltipPrimitive.Content
40
+ data-slot="tooltip-content"
41
+ sideOffset={sideOffset}
42
+ className={cn(
43
+ "bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-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 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance",
44
+ className
45
+ )}
46
+ {...props}>
47
+ {children}
48
+ <TooltipPrimitive.Arrow
49
+ className="bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" />
50
+ </TooltipPrimitive.Content>
51
+ </TooltipPrimitive.Portal>
52
+ );
53
+ }
54
+
55
+ export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
@@ -0,0 +1,12 @@
1
+ import { VideoConference } from "@/library/pages/VideoConference";
2
+ import { ReservationsOverview } from "@/library/pages/ReservationsOverview";
3
+ import { FitnessOverview } from "@/library/pages/FitnessPage";
4
+ import { GroupChat } from "@/library/pages/GroupChat";
5
+
6
+
7
+ export const components = {
8
+ VideoConference,
9
+ GroupChat,
10
+ // ReservationsOverview,
11
+ // FitnessOverview
12
+ };
@@ -0,0 +1,19 @@
1
+ import * as React from "react"
2
+
3
+ const MOBILE_BREAKPOINT = 768
4
+
5
+ export function useIsMobile() {
6
+ const [isMobile, setIsMobile] = React.useState(undefined)
7
+
8
+ React.useEffect(() => {
9
+ const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
10
+ const onChange = () => {
11
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
12
+ }
13
+ mql.addEventListener("change", onChange)
14
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
15
+ return () => mql.removeEventListener("change", onChange);
16
+ }, [])
17
+
18
+ return !!isMobile
19
+ }
@@ -0,0 +1,6 @@
1
+ import { clsx } from "clsx";
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs) {
5
+ return twMerge(clsx(inputs));
6
+ }
@@ -0,0 +1,27 @@
1
+ export const alert = {
2
+ name: 'Alert',
3
+ code: `<div className="bg-blue-50 border border-blue-200 text-blue-800 px-4 py-3 rounded-lg">
4
+ <div className="flex items-start">
5
+ <div className="flex-1">
6
+ <p className="font-medium">Info Alert</p>
7
+ <p className="text-sm mt-1">This is an informational message.</p>
8
+ </div>
9
+ </div>
10
+ </div>
11
+
12
+ <!-- Variants -->
13
+ <div className="bg-green-50 border border-green-200 text-green-800 px-4 py-3 rounded-lg">Success Alert</div>
14
+ <div className="bg-yellow-50 border border-yellow-200 text-yellow-800 px-4 py-3 rounded-lg">Warning Alert</div>
15
+ <div className="bg-red-50 border border-red-200 text-red-800 px-4 py-3 rounded-lg">Error Alert</div>`,
16
+ preview: (
17
+ <div className="space-y-3">
18
+ <div className="bg-blue-50 border border-blue-200 text-blue-800 px-4 py-3 rounded-lg">
19
+ <p className="font-medium">Info Alert</p>
20
+ <p className="text-sm mt-1">This is an informational message.</p>
21
+ </div>
22
+ <div className="bg-green-50 border border-green-200 text-green-800 px-4 py-3 rounded-lg">
23
+ <p className="font-medium">Success!</p>
24
+ </div>
25
+ </div>
26
+ )
27
+ };
@@ -0,0 +1,19 @@
1
+ export const badge = {
2
+ name: 'Badge',
3
+ code: `<span className="px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm font-medium">
4
+ Badge
5
+ </span>
6
+
7
+ <!-- Variants -->
8
+ <span className="px-3 py-1 bg-green-100 text-green-800 rounded-full text-sm font-medium">Success</span>
9
+ <span className="px-3 py-1 bg-yellow-100 text-yellow-800 rounded-full text-sm font-medium">Warning</span>
10
+ <span className="px-3 py-1 bg-red-100 text-red-800 rounded-full text-sm font-medium">Error</span>`,
11
+ preview: (
12
+ <div className="flex flex-wrap gap-2">
13
+ <span className="px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm font-medium">Primary</span>
14
+ <span className="px-3 py-1 bg-green-100 text-green-800 rounded-full text-sm font-medium">Success</span>
15
+ <span className="px-3 py-1 bg-yellow-100 text-yellow-800 rounded-full text-sm font-medium">Warning</span>
16
+ <span className="px-3 py-1 bg-red-100 text-red-800 rounded-full text-sm font-medium">Error</span>
17
+ </div>
18
+ )
19
+ };
@@ -0,0 +1,31 @@
1
+ import { Button } from "@/components/ui/button";
2
+
3
+ export const button = {
4
+ name: 'Button',
5
+ code: `<button className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 active:bg-blue-800 transition-colors font-medium">
6
+ Button
7
+ </button>
8
+
9
+ <!-- Variants -->
10
+ <button className="px-4 py-2 bg-gray-600 text-white rounded-lg hover:bg-gray-700">Secondary</button>
11
+ <button className="px-4 py-2 border-2 border-blue-600 text-blue-600 rounded-lg hover:bg-blue-50">Outline</button>
12
+ <button className="px-4 py-2 text-blue-600 hover:bg-blue-50 rounded-lg">Ghost</button>`,
13
+ preview: (
14
+ <div className="flex flex-wrap gap-2">
15
+ <Button
16
+
17
+ className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 active:bg-blue-800 transition-colors font-medium">
18
+ Primary
19
+ </Button>
20
+ <Button className="px-4 py-2 bg-gray-600 text-white rounded-lg hover:bg-gray-700 transition-colors font-medium">
21
+ Secondary
22
+ </Button>
23
+ <Button className="px-4 py-2 border-2 border-blue-600 text-blue-600 rounded-lg hover:bg-blue-50 transition-colors font-medium">
24
+ Outline
25
+ </Button>
26
+ <button className="px-4 py-2 text-blue-600 hover:bg-blue-50 rounded-lg transition-colors font-medium">
27
+ Ghost
28
+ </button>
29
+ </div>
30
+ ),
31
+ };
@@ -0,0 +1,25 @@
1
+ export const card = {
2
+ name: 'Card',
3
+ code: `<div className="bg-white rounded-lg shadow-md p-6 border border-gray-200">
4
+ <h3 className="text-xl font-bold mb-2">Card Title</h3>
5
+ <p className="text-gray-600">Card content goes here. Add any elements you need.</p>
6
+ </div>
7
+
8
+ <!-- With hover effect -->
9
+ <div className="bg-white rounded-lg shadow-md hover:shadow-xl transition-shadow p-6 border border-gray-200">
10
+ <h3 className="text-xl font-bold mb-2">Hover Card</h3>
11
+ <p className="text-gray-600">This card has a hover effect.</p>
12
+ </div>`,
13
+ preview: (
14
+ <div className="grid gap-4 md:grid-cols-2">
15
+ <div className="bg-white rounded-lg shadow-md p-6 border border-gray-200">
16
+ <h3 className="text-xl font-bold mb-2">Card Title</h3>
17
+ <p className="text-gray-600">Card content goes here. Add any elements you need.</p>
18
+ </div>
19
+ <div className="bg-white rounded-lg shadow-md hover:shadow-xl transition-shadow p-6 border border-gray-200">
20
+ <h3 className="text-xl font-bold mb-2">Hover Card</h3>
21
+ <p className="text-gray-600">This card has a hover effect.</p>
22
+ </div>
23
+ </div>
24
+ ),
25
+ };
@@ -0,0 +1,35 @@
1
+ export const input = {
2
+ name: 'Input',
3
+ code: `<input
4
+ type="text"
5
+ placeholder="Enter text..."
6
+ className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
7
+ />
8
+
9
+ <!-- With label -->
10
+ <div className="space-y-2">
11
+ <label className="block text-sm font-medium text-gray-700">Email</label>
12
+ <input
13
+ type="email"
14
+ placeholder="your@email.com"
15
+ className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
16
+ />
17
+ </div>`,
18
+ preview: (
19
+ <div className="space-y-4 max-w-md">
20
+ <input
21
+ type="text"
22
+ placeholder="Enter text..."
23
+ className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
24
+ />
25
+ <div className="space-y-2">
26
+ <label className="block text-sm font-medium text-gray-700">Email</label>
27
+ <input
28
+ type="email"
29
+ placeholder="your@email.com"
30
+ className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
31
+ />
32
+ </div>
33
+ </div>
34
+ )
35
+ };
@@ -0,0 +1,26 @@
1
+ export const modal = {
2
+ name: 'Modal',
3
+ code: `<!-- Modal Overlay -->
4
+ <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50">
5
+ <div className="bg-white rounded-lg shadow-xl max-w-md w-full p-6">
6
+ <h2 className="text-2xl font-bold mb-4">Modal Title</h2>
7
+ <p className="text-gray-600 mb-6">Modal content goes here. Add any elements you need.</p>
8
+ <div className="flex justify-end gap-2">
9
+ <button className="px-4 py-2 text-gray-600 hover:bg-gray-100 rounded-lg">Cancel</button>
10
+ <button className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700">Confirm</button>
11
+ </div>
12
+ </div>
13
+ </div>`,
14
+ preview: (
15
+ <div className="relative h-64 bg-gray-100 rounded-lg flex items-center justify-center">
16
+ <div className="bg-white rounded-lg shadow-xl max-w-sm w-full p-6 m-4">
17
+ <h2 className="text-xl font-bold mb-2">Modal Preview</h2>
18
+ <p className="text-gray-600 text-sm mb-4">This is how the modal looks.</p>
19
+ <div className="flex justify-end gap-2">
20
+ <button className="px-3 py-1 text-sm text-gray-600 hover:bg-gray-100 rounded">Cancel</button>
21
+ <button className="px-3 py-1 text-sm bg-blue-600 text-white rounded hover:bg-blue-700">Confirm</button>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ )
26
+ };
@@ -0,0 +1,15 @@
1
+ export const textarea = {
2
+ name: 'Textarea',
3
+ code: `<textarea
4
+ placeholder="Enter your message..."
5
+ rows="4"
6
+ className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent resize-none"
7
+ ></textarea>`,
8
+ preview: (
9
+ <textarea
10
+ placeholder="Enter your message..."
11
+ rows="4"
12
+ className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent resize-none"
13
+ ></textarea>
14
+ )
15
+ };
@@ -0,0 +1,16 @@
1
+ export const toggle = {
2
+ name: 'Toggle Switch',
3
+ code: `<!-- Toggle Switch (using checkbox) -->
4
+ <label className="relative inline-flex items-center cursor-pointer">
5
+ <input type="checkbox" className="sr-only peer" />
6
+ <div className="w-11 h-6 bg-gray-300 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600"></div>
7
+ <span className="ml-3 text-sm font-medium text-gray-700">Toggle me</span>
8
+ </label>`,
9
+ preview: (
10
+ <label className="relative inline-flex items-center cursor-pointer">
11
+ <input type="checkbox" className="sr-only peer" />
12
+ <div className="w-11 h-6 bg-gray-300 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600"></div>
13
+ <span className="ml-3 text-sm font-medium text-gray-700">Toggle me</span>
14
+ </label>
15
+ )
16
+ };