gbs-add-block 0.0.84 → 0.0.87
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/README.md +2 -3
- package/index.cjs +1 -0
- package/package.json +1 -1
- package/source/components/bargraph/index.tsx +94 -0
- package/source/components/bargraph/type.ts +11 -0
- package/source/components/formrenderer/index.tsx +5 -5
- package/source/components/formrenderer/types.ts +1 -1
- package/source/components/sidebar/components/MenuItem.tsx +9 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# GBS Building Blocks 2.0 (v0.0.
|
|
1
|
+
# GBS Building Blocks 2.0 (v0.0.87)
|
|
2
2
|
|
|
3
3
|
Latest and upgraded version of GBS building blocks with headless UI and removed dependencies.
|
|
4
4
|
|
|
@@ -6,10 +6,9 @@ Latest and upgraded version of GBS building blocks with headless UI and removed
|
|
|
6
6
|
|
|
7
7
|
For detailed documentation on usage and props, Please visit: [Building Block Documentation v2.0](https://blackmax-designs.gitbook.io/building-block-v2.0)
|
|
8
8
|
|
|
9
|
-
## What's New 🎉 (Ver 0.0.
|
|
9
|
+
## What's New 🎉 (Ver 0.0.87)
|
|
10
10
|
|
|
11
11
|
- Updated for bug fixes.
|
|
12
|
-
- New Component Card, Tabs & SideBar Added
|
|
13
12
|
|
|
14
13
|
## Authors
|
|
15
14
|
|
package/index.cjs
CHANGED
package/package.json
CHANGED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { BarChartProps } from "./type";
|
|
4
|
+
|
|
5
|
+
export const BarChart: React.FC<BarChartProps> = ({
|
|
6
|
+
data,
|
|
7
|
+
height = 300,
|
|
8
|
+
title = "Title",
|
|
9
|
+
showXValue = true,
|
|
10
|
+
}) => {
|
|
11
|
+
const [hoveredBar, setHoveredBar] = useState<number | null>(null);
|
|
12
|
+
const maxValue = Math.max(...data.map((d) => d.value));
|
|
13
|
+
const chartHeight = height * 0.8; // Leave room for labels
|
|
14
|
+
|
|
15
|
+
// Calculate y-axis ticks
|
|
16
|
+
const yAxisTicks = Array.from({ length: 6 }, (_, i) =>
|
|
17
|
+
Math.round((maxValue * i) / 5)
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<div className="w-full p-4">
|
|
22
|
+
<h2 className="text-sm font-bold mb-16 text-gray-800 text-left">
|
|
23
|
+
{title}
|
|
24
|
+
</h2>
|
|
25
|
+
|
|
26
|
+
<div className="flex">
|
|
27
|
+
{/* Y-axis labels */}
|
|
28
|
+
<div className="flex flex-col justify-between pr-2 text-right">
|
|
29
|
+
{yAxisTicks.reverse().map((tick, i) => (
|
|
30
|
+
<div
|
|
31
|
+
key={i}
|
|
32
|
+
className="text-xs text-gray-500 h-8 flex items-center justify-end"
|
|
33
|
+
>
|
|
34
|
+
{tick}
|
|
35
|
+
</div>
|
|
36
|
+
))}
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
{/* Chart area */}
|
|
40
|
+
<div className="flex-1">
|
|
41
|
+
<div className="relative h-48">
|
|
42
|
+
{/* Bars */}
|
|
43
|
+
<div className="absolute bottom-0 left-0 right-0 flex items-end h-40 space-x-1 pt-4">
|
|
44
|
+
{data.map((d, i) => {
|
|
45
|
+
const barHeight = (d.value / maxValue) * chartHeight;
|
|
46
|
+
const isHovered = hoveredBar === i;
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<div key={i} className="flex flex-col items-center flex-1">
|
|
50
|
+
{/* Value label on top of bar when hovered */}
|
|
51
|
+
{isHovered && (
|
|
52
|
+
<div className="mb-1 text-xs font-medium bg-gray-800 text-white px-2 py-1 rounded shadow-lg z-10">
|
|
53
|
+
{d.value}
|
|
54
|
+
</div>
|
|
55
|
+
)}
|
|
56
|
+
|
|
57
|
+
{/* Bar */}
|
|
58
|
+
<div
|
|
59
|
+
className={`w-full ${
|
|
60
|
+
isHovered ? "bg-zinc-800" : "bg-black"
|
|
61
|
+
} rounded-t transition-all duration-200 ease-in-out relative`}
|
|
62
|
+
style={{
|
|
63
|
+
height: `${barHeight}px`,
|
|
64
|
+
boxShadow: isHovered
|
|
65
|
+
? "0 4px 12px rgba(59, 130, 246, 0.5)"
|
|
66
|
+
: "none",
|
|
67
|
+
}}
|
|
68
|
+
onMouseEnter={() => setHoveredBar(i)}
|
|
69
|
+
onMouseLeave={() => setHoveredBar(null)}
|
|
70
|
+
></div>
|
|
71
|
+
</div>
|
|
72
|
+
);
|
|
73
|
+
})}
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
{/* X-axis */}
|
|
78
|
+
<div className="flex border-t border-gray-300 pt-2 mt-2">
|
|
79
|
+
{data.map((d, i) => (
|
|
80
|
+
<div key={i} className="flex-1 text-center">
|
|
81
|
+
<div className="text-sm font-medium text-gray-700">
|
|
82
|
+
{d.label}
|
|
83
|
+
</div>
|
|
84
|
+
{showXValue && (
|
|
85
|
+
<div className="text-xs text-gray-500 mt-1">{d.value}</div>
|
|
86
|
+
)}
|
|
87
|
+
</div>
|
|
88
|
+
))}
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
);
|
|
94
|
+
};
|
|
@@ -12,7 +12,7 @@ import { COMPONENT_MAP, validateField } from "./helperFunctions";
|
|
|
12
12
|
|
|
13
13
|
const FormRenderer: React.FC<FormRendererProps> = ({
|
|
14
14
|
onSubmit,
|
|
15
|
-
|
|
15
|
+
schema = [],
|
|
16
16
|
formFormationClass = "grid grid-cols-1 gap-2",
|
|
17
17
|
formParentClass = "w-96",
|
|
18
18
|
}) => {
|
|
@@ -24,7 +24,7 @@ const FormRenderer: React.FC<FormRendererProps> = ({
|
|
|
24
24
|
const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
|
|
25
25
|
event.preventDefault();
|
|
26
26
|
|
|
27
|
-
const requirementErrorItems =
|
|
27
|
+
const requirementErrorItems = schema
|
|
28
28
|
.filter((item) => item.required && item.name)
|
|
29
29
|
.reduce((errors: string[], item) => {
|
|
30
30
|
const field = formRef.current?.querySelector(
|
|
@@ -76,15 +76,15 @@ const FormRenderer: React.FC<FormRendererProps> = ({
|
|
|
76
76
|
);
|
|
77
77
|
};
|
|
78
78
|
|
|
79
|
-
// If no
|
|
80
|
-
if (!
|
|
79
|
+
// If no schema data is found, return a message
|
|
80
|
+
if (!schema.length) {
|
|
81
81
|
return <div>No Source Data Found</div>;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
return (
|
|
85
85
|
<form ref={formRef} onSubmit={handleSubmit} className={formParentClass}>
|
|
86
86
|
<div className={formFormationClass}>
|
|
87
|
-
{
|
|
87
|
+
{schema.map(renderFormComponent)}
|
|
88
88
|
</div>
|
|
89
89
|
</form>
|
|
90
90
|
);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
1
2
|
import { MenuItem, IconComponent } from "../type";
|
|
2
3
|
|
|
3
4
|
type MenuItemProps = {
|
|
@@ -12,6 +13,13 @@ export const MenuItemComponent = ({
|
|
|
12
13
|
onToggle,
|
|
13
14
|
}: MenuItemProps) => {
|
|
14
15
|
const IconComponent = iconMap[item.icon] || (() => null);
|
|
16
|
+
const [path, setPath] = useState("");
|
|
17
|
+
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (typeof window !== "undefined") {
|
|
20
|
+
setPath(window.location.pathname);
|
|
21
|
+
}
|
|
22
|
+
}, []);
|
|
15
23
|
|
|
16
24
|
return (
|
|
17
25
|
<li>
|
|
@@ -26,7 +34,7 @@ export const MenuItemComponent = ({
|
|
|
26
34
|
: undefined
|
|
27
35
|
}
|
|
28
36
|
className={`flex items-center py-2 px-3 rounded-md text-sm ${
|
|
29
|
-
item.
|
|
37
|
+
item.path === path
|
|
30
38
|
? "bg-gray-100 text-black font-medium"
|
|
31
39
|
: "text-gray-700 hover:bg-gray-50"
|
|
32
40
|
}`}
|