ui-arreya-components 0.0.9 → 0.0.11

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.
@@ -0,0 +1,35 @@
1
+ # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2
+ # For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
3
+
4
+ name: Node.js Package
5
+
6
+ on:
7
+ release:
8
+ types: [created]
9
+
10
+ jobs:
11
+ build:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: actions/setup-node@v4
16
+ with:
17
+ node-version: 20
18
+ - run: npm ci
19
+ - run: npm test
20
+ - run: npm prepublish
21
+
22
+ publish-npm:
23
+ needs: build
24
+ runs-on: ubuntu-latest
25
+ steps:
26
+ - uses: actions/checkout@v4
27
+ - uses: actions/setup-node@v4
28
+ with:
29
+ node-version: 20
30
+ registry-url: https://registry.npmjs.org/
31
+ - run: npm ci
32
+ - run: npm prepublish
33
+ - run: npm publish
34
+ env:
35
+ NODE_AUTH_TOKEN: ${{secrets.npm_token}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ui-arreya-components",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "type": "module",
5
5
  "types": "dist/index.d.ts",
6
6
  "exports": {
@@ -24,7 +24,7 @@
24
24
  "build-storybook": "concurrently 'npm run build-storybook:css' 'storybook build'",
25
25
  "build-storybook:css": "tailwindcss -m -i ./src/styles/tailwind.css -o ./src/index.css",
26
26
  "prepublish": "npm run build",
27
- "publish": "npm publish"
27
+ "test": "echo 'setup unit testing'"
28
28
  },
29
29
  "peerDependencies": {
30
30
  "react": "^18.0.0",
@@ -0,0 +1,16 @@
1
+ #!/bin/bash
2
+
3
+ # Starting fresh
4
+ rm src/index.ts
5
+
6
+ # Add Components
7
+ for import in `ls src/components/ui/ | grep -v '.stories.' | cut -f1 -d\.`;
8
+ do
9
+ echo 'export * from "./components/ui/'$import'"' >> src/index.ts
10
+ done
11
+
12
+ # Add Features
13
+ for import in `ls src/components/feature/ | grep -v '.stories.' | cut -f1 -d\.`;
14
+ do
15
+ echo 'export * from "./components/feature/'${import}'"' >> src/index.ts
16
+ done
@@ -0,0 +1,138 @@
1
+ import type { Meta, StoryObj } from "@storybook/react"
2
+ import { GraphCard } from "./graph-card"
3
+ import { Area, AreaChart, ResponsiveContainer } from "recharts"
4
+
5
+ const meta: Meta<typeof GraphCard> = {
6
+ title: "Feature/GraphCard",
7
+ component: GraphCard,
8
+ parameters: {
9
+ layout: "centered",
10
+ },
11
+ tags: ["autodocs"],
12
+ argTypes: {
13
+ title: {
14
+ control: "text",
15
+ description: "The title of the graph card",
16
+ },
17
+ description: {
18
+ control: "text",
19
+ description: "Optional description text below the title",
20
+ },
21
+ value: {
22
+ control: "text",
23
+ description: "The primary value to display (e.g., total, average)",
24
+ },
25
+ change: {
26
+ control: "number",
27
+ description: "Percentage change to display",
28
+ },
29
+ changeType: {
30
+ control: { type: "select" },
31
+ options: ["increase", "decrease", "neutral"],
32
+ description: "Type of change (affects color and icon)",
33
+ },
34
+ changeLabel: {
35
+ control: "text",
36
+ description: "Label to display after the change value",
37
+ },
38
+ isLoading: {
39
+ control: "boolean",
40
+ description: "Whether to show a loading state",
41
+ },
42
+ },
43
+ }
44
+
45
+ export default meta
46
+ type Story = StoryObj<typeof GraphCard>
47
+
48
+ // Simple example with minimal data
49
+ export const Simple: Story = {
50
+ args: {
51
+ title: "Monthly Sales",
52
+ description: "Total sales for the current month",
53
+ value: "$12,345",
54
+ chart: (
55
+ <ResponsiveContainer width="100%" height="100%">
56
+ <AreaChart
57
+ data={[
58
+ { month: "Jan", value: 1000 },
59
+ { month: "Feb", value: 2000 },
60
+ { month: "Mar", value: 1500 },
61
+ { month: "Apr", value: 3000 },
62
+ { month: "May", value: 2500 },
63
+ { month: "Jun", value: 4000 },
64
+ ]}
65
+ >
66
+ <Area type="monotone" dataKey="value" stroke="hsl(var(--primary))" fill="hsl(var(--primary) / 0.2)" />
67
+ </AreaChart>
68
+ </ResponsiveContainer>
69
+ ),
70
+ },
71
+ }
72
+
73
+ // Example with positive change
74
+ export const PositiveChange: Story = {
75
+ args: {
76
+ title: "Website Traffic",
77
+ description: "Unique visitors per day",
78
+ value: "12,456",
79
+ change: 23.5,
80
+ changeType: "increase",
81
+ changeLabel: "vs last week",
82
+ chart: (
83
+ <ResponsiveContainer width="100%" height="100%">
84
+ <AreaChart
85
+ data={[
86
+ { day: "Mon", value: 1000 },
87
+ { day: "Tue", value: 2000 },
88
+ { day: "Wed", value: 3000 },
89
+ { day: "Thu", value: 2500 },
90
+ { day: "Fri", value: 4000 },
91
+ { day: "Sat", value: 3500 },
92
+ { day: "Sun", value: 4500 },
93
+ ]}
94
+ >
95
+ <Area type="monotone" dataKey="value" stroke="hsl(var(--primary))" fill="hsl(var(--primary) / 0.2)" />
96
+ </AreaChart>
97
+ </ResponsiveContainer>
98
+ ),
99
+ },
100
+ }
101
+
102
+ // Example with negative change
103
+ export const NegativeChange: Story = {
104
+ args: {
105
+ title: "Conversion Rate",
106
+ description: "Percentage of visitors who make a purchase",
107
+ value: "3.2%",
108
+ change: 5.7,
109
+ changeType: "decrease",
110
+ changeLabel: "vs last month",
111
+ chart: (
112
+ <ResponsiveContainer width="100%" height="100%">
113
+ <AreaChart
114
+ data={[
115
+ { week: "W1", value: 4.5 },
116
+ { week: "W2", value: 4.2 },
117
+ { week: "W3", value: 3.8 },
118
+ { week: "W4", value: 3.5 },
119
+ { week: "W5", value: 3.2 },
120
+ ]}
121
+ >
122
+ <Area type="monotone" dataKey="value" stroke="hsl(var(--destructive))" fill="hsl(var(--destructive) / 0.2)" />
123
+ </AreaChart>
124
+ </ResponsiveContainer>
125
+ ),
126
+ },
127
+ }
128
+
129
+ // Loading state
130
+ export const Loading: Story = {
131
+ args: {
132
+ title: "Revenue",
133
+ description: "Total revenue this quarter",
134
+ value: "$143,245",
135
+ isLoading: true,
136
+ chart: <div />, // This won't be shown in loading state
137
+ },
138
+ }
@@ -0,0 +1,113 @@
1
+ import type React from "react"
2
+ import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
3
+ import { ChartContainer } from "@/components/ui/chart"
4
+ import { cn } from "@/lib/utils"
5
+ import { ArrowDownIcon, ArrowUpIcon, MoreHorizontal } from "lucide-react"
6
+ import { Button } from "@/components/ui/button"
7
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
8
+
9
+ export interface GraphCardProps {
10
+ title: string
11
+ description?: string
12
+ chart: React.ReactNode
13
+ value?: string | number
14
+ previousValue?: string | number
15
+ change?: number
16
+ changeType?: "increase" | "decrease" | "neutral"
17
+ changeLabel?: string
18
+ className?: string
19
+ footerContent?: React.ReactNode
20
+ menuItems?: Array<{ label: string; onClick: () => void }>
21
+ chartConfig?: Record<string, any>
22
+ isLoading?: boolean
23
+ }
24
+
25
+ export function GraphCard({
26
+ title,
27
+ description,
28
+ chart,
29
+ value,
30
+ previousValue,
31
+ change,
32
+ changeType,
33
+ changeLabel,
34
+ className,
35
+ footerContent,
36
+ menuItems,
37
+ chartConfig,
38
+ isLoading = false,
39
+ }: GraphCardProps) {
40
+ const renderChangeIndicator = () => {
41
+ if (changeType === "increase") {
42
+ return <ArrowUpIcon className="h-4 w-4 text-emerald-500" />
43
+ } else if (changeType === "decrease") {
44
+ return <ArrowDownIcon className="h-4 w-4 text-red-500" />
45
+ }
46
+ return null
47
+ }
48
+
49
+ const getChangeTextColor = () => {
50
+ if (changeType === "increase") return "text-emerald-500"
51
+ if (changeType === "decrease") return "text-red-500"
52
+ return "text-muted-foreground"
53
+ }
54
+
55
+ return (
56
+ <Card className={cn("overflow-hidden", className)}>
57
+ <CardHeader className="flex flex-row items-center justify-between pb-2">
58
+ <div>
59
+ <CardTitle className="text-base font-medium">{title}</CardTitle>
60
+ {description && <CardDescription>{description}</CardDescription>}
61
+ </div>
62
+ {menuItems && menuItems.length > 0 && (
63
+ <DropdownMenu>
64
+ <DropdownMenuTrigger asChild>
65
+ <Button variant="ghost" className="h-8 w-8 p-0">
66
+ <span className="sr-only">Open menu</span>
67
+ <MoreHorizontal className="h-4 w-4" />
68
+ </Button>
69
+ </DropdownMenuTrigger>
70
+ <DropdownMenuContent align="end">
71
+ {menuItems.map((item, index) => (
72
+ <DropdownMenuItem key={index} onClick={item.onClick}>
73
+ {item.label}
74
+ </DropdownMenuItem>
75
+ ))}
76
+ </DropdownMenuContent>
77
+ </DropdownMenu>
78
+ )}
79
+ </CardHeader>
80
+ <CardContent className="pb-2">
81
+ {value && (
82
+ <div className="flex items-center justify-between">
83
+ <div className="space-y-1">
84
+ <p className="text-2xl font-bold">{value}</p>
85
+ {(change !== undefined || previousValue) && (
86
+ <div className="flex items-center text-xs">
87
+ {renderChangeIndicator()}
88
+ <span className={cn("ml-1", getChangeTextColor())}>
89
+ {change !== undefined && `${Math.abs(change)}%`}
90
+ {previousValue && !change && `from ${previousValue}`}
91
+ </span>
92
+ {changeLabel && <span className="ml-1 text-muted-foreground">{changeLabel}</span>}
93
+ </div>
94
+ )}
95
+ </div>
96
+ </div>
97
+ )}
98
+ <div className={cn("mt-4", value ? "h-[180px]" : "h-[240px]")}>
99
+ {isLoading ? (
100
+ <div className="flex h-full items-center justify-center">
101
+ <div className="h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent"></div>
102
+ </div>
103
+ ) : chartConfig ? (
104
+ <ChartContainer config={chartConfig}>{chart}</ChartContainer>
105
+ ) : (
106
+ chart
107
+ )}
108
+ </div>
109
+ </CardContent>
110
+ {footerContent && <CardFooter>{footerContent}</CardFooter>}
111
+ </Card>
112
+ )
113
+ }
@@ -2,7 +2,7 @@ import type { Meta, StoryObj } from "@storybook/react"
2
2
  import { Header } from "./header"
3
3
 
4
4
  const meta: Meta<typeof Header> = {
5
- title: "Components/Header",
5
+ title: "Feature/Header",
6
6
  component: Header,
7
7
  parameters: {
8
8
  layout: "fullscreen",
@@ -9,7 +9,7 @@ import {
9
9
  } from "@/components/ui/breadcrumb"
10
10
  import { ChevronRight, Home } from "lucide-react"
11
11
 
12
- export type BreadcrumbItem = {
12
+ type BreadcrumbItem = {
13
13
  label: string
14
14
  href?: string
15
15
  isCurrentPage?: boolean
@@ -26,7 +26,7 @@ interface HeaderProps {
26
26
  export function Header({ title, breadcrumbItems = [], showHomeLink = true, className = "", children }: HeaderProps) {
27
27
  return (
28
28
  <header className={`border-b pb-4 ${className}`}>
29
- <div className="container mx-auto px-4">
29
+ <div className="container mx-auto p-4">
30
30
  {(breadcrumbItems.length > 0 || showHomeLink) && (
31
31
  <Breadcrumb className="mb-2">
32
32
  <BreadcrumbList>
@@ -1 +1,2 @@
1
1
  export * from './ui/accordion'
2
+ export * from './features/GraphCard'
@@ -8,7 +8,7 @@ const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
8
8
  <input
9
9
  type={type}
10
10
  className={cn(
11
- "flex h-9 w-full rounded-md border focus:border-[--primary] border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
11
+ "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
12
12
  className
13
13
  )}
14
14
  ref={ref}
@@ -1,5 +1,3 @@
1
- "use client"
2
-
3
1
  import * as React from "react"
4
2
  import * as SheetPrimitive from "@radix-ui/react-dialog"
5
3
  import { cva, type VariantProps } from "class-variance-authority"
@@ -3,7 +3,7 @@ import { Toaster as Sonner } from "sonner"
3
3
 
4
4
  type ToasterProps = React.ComponentProps<typeof Sonner>
5
5
 
6
- const Toaster = ({ ...props }: ToasterProps) => {
6
+ const SonnerToaster = ({ ...props }: ToasterProps) => {
7
7
  const { theme = "system" } = useTheme()
8
8
 
9
9
  return (
@@ -26,4 +26,4 @@ const Toaster = ({ ...props }: ToasterProps) => {
26
26
  )
27
27
  }
28
28
 
29
- export { Toaster }
29
+ export { SonnerToaster }
package/src/index.css CHANGED
@@ -1009,10 +1009,18 @@ body{
1009
1009
  height: 2.25rem;
1010
1010
  }
1011
1011
 
1012
+ .h-\[180px\]{
1013
+ height: 180px;
1014
+ }
1015
+
1012
1016
  .h-\[1px\]{
1013
1017
  height: 1px;
1014
1018
  }
1015
1019
 
1020
+ .h-\[240px\]{
1021
+ height: 240px;
1022
+ }
1023
+
1016
1024
  .h-\[var\(--radix-navigation-menu-viewport-height\)\]{
1017
1025
  height: var(--radix-navigation-menu-viewport-height);
1018
1026
  }
@@ -1538,6 +1546,10 @@ body{
1538
1546
  border-width: 2px;
1539
1547
  }
1540
1548
 
1549
+ .border-4{
1550
+ border-width: 4px;
1551
+ }
1552
+
1541
1553
  .border-\[1\.5px\]{
1542
1554
  border-width: 1.5px;
1543
1555
  }
@@ -1768,6 +1780,10 @@ body{
1768
1780
  padding-bottom: 0px;
1769
1781
  }
1770
1782
 
1783
+ .pb-2{
1784
+ padding-bottom: 0.5rem;
1785
+ }
1786
+
1771
1787
  .pb-3{
1772
1788
  padding-bottom: 0.75rem;
1773
1789
  }
@@ -1924,6 +1940,11 @@ body{
1924
1940
  color: hsl(var(--destructive-foreground));
1925
1941
  }
1926
1942
 
1943
+ .text-emerald-500{
1944
+ --tw-text-opacity: 1;
1945
+ color: rgb(16 185 129 / var(--tw-text-opacity, 1));
1946
+ }
1947
+
1927
1948
  .text-foreground{
1928
1949
  color: var(--foreground);
1929
1950
  }
@@ -1944,6 +1965,11 @@ body{
1944
1965
  color: hsl(var(--primary-foreground));
1945
1966
  }
1946
1967
 
1968
+ .text-red-500{
1969
+ --tw-text-opacity: 1;
1970
+ color: rgb(239 68 68 / var(--tw-text-opacity, 1));
1971
+ }
1972
+
1947
1973
  .text-secondary-foreground{
1948
1974
  color: var(--secondary-foreground);
1949
1975
  }
@@ -2377,10 +2403,6 @@ h1, h2, h3, h4 {
2377
2403
  background-color: hsl(var(--sidebar-border));
2378
2404
  }
2379
2405
 
2380
- .focus\:border-\[--primary\]:focus{
2381
- border-color: var(--primary);
2382
- }
2383
-
2384
2406
  .focus\:bg-accent:focus{
2385
2407
  background-color: var(--accent);
2386
2408
  }
@@ -2455,10 +2477,6 @@ h1, h2, h3, h4 {
2455
2477
  --tw-ring-offset-color: var(--background);
2456
2478
  }
2457
2479
 
2458
- .active\:border-\[--primary\]:active{
2459
- border-color: var(--primary);
2460
- }
2461
-
2462
2480
  .active\:bg-sidebar-accent:active{
2463
2481
  background-color: hsl(var(--sidebar-accent));
2464
2482
  }
package/src/index.ts CHANGED
@@ -1,51 +1,50 @@
1
- export { Button } from './components/ui/button';
2
- export {
3
- Dialog,
4
- DialogPortal,
5
- DialogOverlay,
6
- DialogTrigger,
7
- DialogClose,
8
- DialogContent,
9
- DialogHeader,
10
- DialogFooter,
11
- DialogTitle,
12
- DialogDescription,
13
- } from './components/ui/dialog';
14
- export {
15
- Sidebar,
16
- SidebarContent,
17
- SidebarFooter,
18
- SidebarGroup,
19
- SidebarGroupAction,
20
- SidebarGroupContent,
21
- SidebarGroupLabel,
22
- SidebarHeader,
23
- SidebarInput,
24
- SidebarInset,
25
- SidebarMenu,
26
- SidebarMenuAction,
27
- SidebarMenuBadge,
28
- SidebarMenuButton,
29
- SidebarMenuItem,
30
- SidebarMenuSkeleton,
31
- SidebarMenuSub,
32
- SidebarMenuSubButton,
33
- SidebarMenuSubItem,
34
- SidebarProvider,
35
- SidebarRail,
36
- SidebarSeparator,
37
- SidebarTrigger,
38
- useSidebar,
39
- } from './components/ui/sidebar';
40
- export {
41
- Breadcrumb,
42
- BreadcrumbList,
43
- BreadcrumbItem,
44
- BreadcrumbLink,
45
- BreadcrumbPage,
46
- BreadcrumbSeparator,
47
- BreadcrumbEllipsis,
48
- } from './components/ui/breadcrumb';
49
- export {
50
- Header
51
- } from './components/feature/header'
1
+ export * from "./components/ui/accordion"
2
+ export * from "./components/ui/alert-dialog"
3
+ export * from "./components/ui/alert"
4
+ export * from "./components/ui/aspect-ratio"
5
+ export * from "./components/ui/avatar"
6
+ export * from "./components/ui/badge"
7
+ export * from "./components/ui/breadcrumb"
8
+ export * from "./components/ui/button"
9
+ export * from "./components/ui/card"
10
+ export * from "./components/ui/carousel"
11
+ export * from "./components/ui/chart"
12
+ export * from "./components/ui/checkbox"
13
+ export * from "./components/ui/collapsible"
14
+ export * from "./components/ui/context-menu"
15
+ export * from "./components/ui/dialog"
16
+ export * from "./components/ui/drawer"
17
+ export * from "./components/ui/dropdown-menu"
18
+ export * from "./components/ui/form"
19
+ export * from "./components/ui/hover-card"
20
+ export * from "./components/ui/index"
21
+ export * from "./components/ui/input-otp"
22
+ export * from "./components/ui/input"
23
+ export * from "./components/ui/label"
24
+ export * from "./components/ui/menubar"
25
+ export * from "./components/ui/navigation-menu"
26
+ export * from "./components/ui/pagination"
27
+ export * from "./components/ui/popover"
28
+ export * from "./components/ui/progress"
29
+ export * from "./components/ui/radio-group"
30
+ export * from "./components/ui/resizable"
31
+ export * from "./components/ui/scroll-area"
32
+ export * from "./components/ui/select"
33
+ export * from "./components/ui/separator"
34
+ export * from "./components/ui/sheet"
35
+ export * from "./components/ui/sidebar"
36
+ export * from "./components/ui/skeleton"
37
+ export * from "./components/ui/slider"
38
+ export * from "./components/ui/sonner"
39
+ export * from "./components/ui/switch"
40
+ export * from "./components/ui/table"
41
+ export * from "./components/ui/tabs"
42
+ export * from "./components/ui/textarea"
43
+ export * from "./components/ui/toast"
44
+ export * from "./components/ui/toaster"
45
+ export * from "./components/ui/toggle-group"
46
+ export * from "./components/ui/toggle"
47
+ export * from "./components/ui/tooltip"
48
+ export * from "./components/feature/graph-card"
49
+ export * from "./components/feature/header"
50
+ export * from "./components/feature/login-form"
@@ -92,5 +92,3 @@ const config: Config = {
92
92
  }
93
93
 
94
94
  export default config
95
-
96
-